gooddata 2.1.8-java → 2.1.13-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/.travis.yml +2 -4
- data/CHANGELOG.md +43 -0
- data/Dockerfile +19 -4
- data/Dockerfile.jruby +4 -4
- data/Dockerfile.ruby +5 -4
- data/README.md +2 -0
- data/SDK_VERSION +1 -1
- data/VERSION +1 -1
- data/bin/provision.sh +2 -0
- data/bin/release.sh +2 -0
- data/bin/rollout.sh +2 -0
- data/bin/run_brick.rb +31 -7
- data/bin/test_projects_cleanup.rb +10 -2
- data/bin/user_filters.sh +2 -0
- data/ci.rake +1 -1
- 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 +6 -2
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +22 -12
- data/lcm.rake +14 -0
- data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +68 -0
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +2 -1
- data/lib/gooddata/bricks/middleware/mask_logger_decorator.rb +5 -1
- data/lib/gooddata/bricks/pipeline.rb +7 -0
- 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/cloud_resouce_factory.rb +28 -0
- data/lib/gooddata/cloud_resources/cloud_resource_client.rb +24 -0
- data/lib/gooddata/cloud_resources/cloud_resources.rb +12 -0
- data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +15 -0
- data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +101 -0
- data/lib/gooddata/cloud_resources/snowflake/drivers/.gitkeepme +0 -0
- data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +84 -0
- data/lib/gooddata/exceptions/invalid_env_error.rb +15 -0
- data/lib/gooddata/helpers/data_helper.rb +10 -0
- data/lib/gooddata/helpers/data_source_helpers.rb +47 -0
- data/lib/gooddata/helpers/global_helpers.rb +4 -0
- data/lib/gooddata/helpers/global_helpers_params.rb +6 -9
- 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_segment_clients.rb +4 -1
- data/lib/gooddata/lcm/actions/collect_segments.rb +1 -2
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +7 -6
- data/lib/gooddata/lcm/actions/create_segment_masters.rb +5 -3
- 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_clients.rb +1 -1
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +1 -2
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +20 -3
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +23 -3
- data/lib/gooddata/lcm/actions/synchronize_users.rb +50 -30
- data/lib/gooddata/lcm/actions/update_release_table.rb +7 -1
- data/lib/gooddata/lcm/exceptions/lcm_execution_error.rb +16 -0
- data/lib/gooddata/lcm/helpers/release_table_helper.rb +16 -8
- data/lib/gooddata/lcm/lcm2.rb +28 -5
- data/lib/gooddata/models/domain.rb +17 -15
- data/lib/gooddata/models/execution.rb +0 -1
- data/lib/gooddata/models/execution_detail.rb +0 -1
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/profile.rb +33 -11
- data/lib/gooddata/models/project.rb +120 -31
- data/lib/gooddata/models/project_creator.rb +2 -0
- data/lib/gooddata/models/schedule.rb +0 -1
- data/lib/gooddata/rest/client.rb +2 -2
- data/lib/gooddata/rest/connection.rb +5 -3
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +32 -13
- data/lib/gooddata/extensions/hash.rb +0 -18
@@ -190,6 +190,9 @@ module GoodData
|
|
190
190
|
create_non_existing_user_groups: create_non_existing_user_groups,
|
191
191
|
user_groups_cache: nil
|
192
192
|
}
|
193
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, data_rows=#{new_users.size}")
|
194
|
+
|
195
|
+
GoodData.logger.info("Synchronizing in mode \"#{mode}\"")
|
193
196
|
results = case mode
|
194
197
|
when 'add_to_organization'
|
195
198
|
domain.create_users(new_users.uniq { |u| u[:login] || u[:email] })
|
@@ -197,6 +200,8 @@ module GoodData
|
|
197
200
|
user_ids = new_users.uniq { |u| u[:login] || u[:email] }.map { |u| u[:login] || u[:email] }
|
198
201
|
users = user_ids.map { |u| domain.users(u, client: client) }
|
199
202
|
params.gdc_logger.warn "Deleting #{users.count} users from domain #{domain_name}"
|
203
|
+
|
204
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, domain=#{domain_name}, data_rows=#{users.count}")
|
200
205
|
users.map(&:delete)
|
201
206
|
when 'sync_project'
|
202
207
|
project.import_users(new_users, common_params)
|
@@ -204,6 +209,8 @@ module GoodData
|
|
204
209
|
new_users.group_by { |u| u[:pid] }.flat_map do |project_id, users|
|
205
210
|
begin
|
206
211
|
project = client.projects(project_id)
|
212
|
+
|
213
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{project_id}, data_rows=#{users.count}")
|
207
214
|
project.import_users(users, common_params)
|
208
215
|
rescue RestClient::ResourceNotFound
|
209
216
|
fail "Project \"#{project_id}\" was not found. Please check your project ids in the source file"
|
@@ -215,6 +222,8 @@ module GoodData
|
|
215
222
|
end
|
216
223
|
when 'sync_one_project_based_on_pid'
|
217
224
|
filtered_users = new_users.select { |u| u[:pid] == project.pid }
|
225
|
+
|
226
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, data_rows=#{filtered_users.count}")
|
218
227
|
project.import_users(filtered_users, common_params)
|
219
228
|
when 'sync_one_project_based_on_custom_id'
|
220
229
|
filter_value = UserBricksHelper.resolve_client_id(domain, project, data_product)
|
@@ -235,6 +244,7 @@ module GoodData
|
|
235
244
|
end
|
236
245
|
|
237
246
|
GoodData.logger.info("Project #{project.pid} will receive #{filtered_users.count} from #{new_users.count} users")
|
247
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{project.pid}, filtered_users=#{filtered_users.count}, data_rows=#{new_users.count}")
|
238
248
|
project.import_users(filtered_users, common_params)
|
239
249
|
when 'sync_multiple_projects_based_on_custom_id'
|
240
250
|
all_clients = domain.clients(:all, data_product).to_a
|
@@ -248,6 +258,8 @@ module GoodData
|
|
248
258
|
fail "Client #{client_id} does not have project." unless project
|
249
259
|
|
250
260
|
GoodData.logger.info("Project #{project.pid} of client #{client_id} will receive #{users.count} users")
|
261
|
+
|
262
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{project.pid}, data_rows=#{users.count}")
|
251
263
|
project.import_users(users, common_params)
|
252
264
|
end
|
253
265
|
when 'sync_domain_client_workspaces'
|
@@ -280,6 +292,8 @@ module GoodData
|
|
280
292
|
|
281
293
|
working_client_ids << client_id.to_s
|
282
294
|
GoodData.logger.info("Project #{project.pid} of client #{client_id} will receive #{users.count} users")
|
295
|
+
|
296
|
+
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{project.pid}, data_rows=#{users.count}")
|
283
297
|
project.import_users(users, common_params)
|
284
298
|
end
|
285
299
|
|
@@ -303,13 +317,18 @@ module GoodData
|
|
303
317
|
next
|
304
318
|
end
|
305
319
|
GoodData.logger.info("Synchronizing all users in project #{project.pid} of client #{c.client_id}")
|
320
|
+
|
321
|
+
GoodData.gd_logger.info("Synchronizing all users in project_id=#{project.pid}, client_id=#{c.client_id}")
|
306
322
|
res += project.import_users([], common_params)
|
307
323
|
end
|
308
324
|
end
|
309
325
|
|
310
326
|
res
|
311
327
|
when 'sync_domain_and_project'
|
328
|
+
GoodData.gd_logger.info("Create users in mode=#{mode}, data_rows=#{new_users.count}")
|
312
329
|
domain.create_users(new_users, ignore_failures: ignore_failures)
|
330
|
+
|
331
|
+
GoodData.gd_logger.info("Import users in mode=#{mode}, data_rows=#{new_users.count}")
|
313
332
|
project.import_users(new_users, common_params)
|
314
333
|
end
|
315
334
|
|
@@ -328,38 +347,33 @@ module GoodData
|
|
328
347
|
end
|
329
348
|
|
330
349
|
def load_data(params, data_source)
|
331
|
-
first_name_column = params.first_name_column || 'first_name'
|
332
|
-
last_name_column = params.last_name_column || 'last_name'
|
333
|
-
login_column = params.login_column || 'login'
|
334
|
-
password_column = params.password_column || 'password'
|
335
|
-
email_column = params.email_column || 'email'
|
336
|
-
role_column = params.role_column || 'role'
|
337
|
-
sso_provider_column = params.sso_provider_column || 'sso_provider'
|
338
|
-
authentication_modes_column = params.authentication_modes_column || 'authentication_modes'
|
339
|
-
user_groups_column = params.user_groups_column || 'user_groups'
|
340
|
-
language_column = params.language_column || 'language'
|
341
|
-
company_column = params.company_column || 'company'
|
342
|
-
position_column = params.position_column || 'position'
|
343
|
-
country_column = params.country_column || 'country'
|
344
|
-
phone_column = params.phone_column || 'phone'
|
345
|
-
ip_whitelist_column = params.ip_whitelist_column || 'ip_whitelist'
|
350
|
+
first_name_column = params.first_name_column&.downcase || 'first_name'
|
351
|
+
last_name_column = params.last_name_column&.downcase || 'last_name'
|
352
|
+
login_column = params.login_column&.downcase || 'login'
|
353
|
+
password_column = params.password_column&.downcase || 'password'
|
354
|
+
email_column = params.email_column&.downcase || 'email'
|
355
|
+
role_column = params.role_column&.downcase || 'role'
|
356
|
+
sso_provider_column = params.sso_provider_column&.downcase || 'sso_provider'
|
357
|
+
authentication_modes_column = params.authentication_modes_column&.downcase || 'authentication_modes'
|
358
|
+
user_groups_column = params.user_groups_column&.downcase || 'user_groups'
|
359
|
+
language_column = params.language_column&.downcase || 'language'
|
360
|
+
company_column = params.company_column&.downcase || 'company'
|
361
|
+
position_column = params.position_column&.downcase || 'position'
|
362
|
+
country_column = params.country_column&.downcase || 'country'
|
363
|
+
phone_column = params.phone_column&.downcase || 'phone'
|
364
|
+
ip_whitelist_column = params.ip_whitelist_column&.downcase || 'ip_whitelist'
|
346
365
|
|
347
366
|
sso_provider = params.sso_provider
|
348
367
|
authentication_modes = params.authentication_modes || []
|
349
368
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
else
|
354
|
-
tmp = without_check(PARAMS, params) do
|
355
|
-
File.open(data_source.realize(params), 'r:UTF-8')
|
356
|
-
end
|
369
|
+
tmp = without_check(PARAMS, params) do
|
370
|
+
File.open(data_source.realize(params), 'r:UTF-8')
|
371
|
+
end
|
357
372
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
end
|
373
|
+
begin
|
374
|
+
data = read_csv_file(tmp)
|
375
|
+
rescue Exception => e # rubocop:disable RescueException
|
376
|
+
fail "There was an error during loading users from csv file. Message: #{e.message}. Error: #{e}"
|
363
377
|
end
|
364
378
|
|
365
379
|
data.map do |row|
|
@@ -379,12 +393,18 @@ module GoodData
|
|
379
393
|
ip_whitelist = row[ip_whitelist_column] || row[ip_whitelist_column.to_sym]
|
380
394
|
ip_whitelist = ip_whitelist.split(',').map(&:strip) if ip_whitelist
|
381
395
|
|
396
|
+
user_login = row[login_column] || row[login_column.to_sym]
|
397
|
+
user_login = user_login.strip unless user_login.nil?
|
398
|
+
|
399
|
+
user_email = row[email_column] || row[login_column] || row[email_column.to_sym] || row[login_column.to_sym]
|
400
|
+
user_email = user_email.strip unless user_email.nil?
|
401
|
+
|
382
402
|
{
|
383
403
|
:first_name => row[first_name_column] || row[first_name_column.to_sym],
|
384
404
|
:last_name => row[last_name_column] || row[last_name_column.to_sym],
|
385
|
-
:login =>
|
405
|
+
:login => user_login,
|
386
406
|
:password => row[password_column] || row[password_column.to_sym],
|
387
|
-
:email =>
|
407
|
+
:email => user_email,
|
388
408
|
:role => row[role_column] || row[role_column.to_sym],
|
389
409
|
:sso_provider => sso_provider || row[sso_provider_column] || row[sso_provider_column.to_sym],
|
390
410
|
:authentication_modes => modes,
|
@@ -405,7 +425,7 @@ module GoodData
|
|
405
425
|
res = []
|
406
426
|
row_count = 0
|
407
427
|
|
408
|
-
CSV.foreach(path, :headers => true) do |row|
|
428
|
+
CSV.foreach(path, :headers => true, :header_converters => :downcase, :encoding => 'utf-8') do |row|
|
409
429
|
if block_given?
|
410
430
|
data = yield row
|
411
431
|
else
|
@@ -39,6 +39,7 @@ module GoodData
|
|
39
39
|
class << self
|
40
40
|
def call(params)
|
41
41
|
client = params.gdc_gd_client
|
42
|
+
GoodData.gd_logger.info("Update release table: use_nfs=#{params.ads_client.nil?}")
|
42
43
|
|
43
44
|
domain_name = params.organization || params.domain
|
44
45
|
fail "Either organisation or domain has to be specified in params" unless domain_name
|
@@ -48,6 +49,7 @@ module GoodData
|
|
48
49
|
segment_id = segment_in.segment_id
|
49
50
|
|
50
51
|
placeholders = {
|
52
|
+
data_product_id: segment_in[:data_product_id],
|
51
53
|
segment_id: segment_in[:segment_id],
|
52
54
|
master_project_id: segment_in[:master_pid],
|
53
55
|
version: segment_in[:version],
|
@@ -83,7 +85,11 @@ module GoodData
|
|
83
85
|
|
84
86
|
params.ads_client.execute(query)
|
85
87
|
else
|
86
|
-
|
88
|
+
data_product_id = placeholders[:data_product_id]
|
89
|
+
segment_id = placeholders[:segment_id]
|
90
|
+
master_pid = placeholders[:master_project_id]
|
91
|
+
version = placeholders[:version]
|
92
|
+
GoodData::LCM2::Helpers.update_latest_master_to_nfs(domain_id, data_product_id, segment_id, master_pid, version)
|
87
93
|
end
|
88
94
|
end
|
89
95
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright (c) 2010-2019 GoodData Corporation. All rights reserved.
|
2
|
+
# This source code is licensed under the BSD-style license found in the
|
3
|
+
# LICENSE file in the root directory of this source tree.
|
4
|
+
|
5
|
+
module GoodData
|
6
|
+
class LcmExecutionError < RuntimeError
|
7
|
+
DEFAULT_MSG = 'Error during lcm execution'
|
8
|
+
|
9
|
+
attr_reader :summary_error
|
10
|
+
|
11
|
+
def initialize(summary_error, message = DEFAULT_MSG)
|
12
|
+
super(message)
|
13
|
+
@summary_error = summary_error
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -8,7 +8,7 @@ module GoodData
|
|
8
8
|
module LCM2
|
9
9
|
class Helpers
|
10
10
|
DEFAULT_TABLE_NAME = 'LCM_RELEASE'
|
11
|
-
DEFAULT_NFS_DIRECTORY = 'release-tables'
|
11
|
+
DEFAULT_NFS_DIRECTORY = '/release-tables'
|
12
12
|
|
13
13
|
class << self
|
14
14
|
def latest_master_project_from_ads(release_table_name, ads_client, segment_id)
|
@@ -25,22 +25,30 @@ module GoodData
|
|
25
25
|
sorted.last
|
26
26
|
end
|
27
27
|
|
28
|
-
def latest_master_project_from_nfs(domain_id, segment_id)
|
29
|
-
|
30
|
-
data
|
28
|
+
def latest_master_project_from_nfs(domain_id, data_product_id, segment_id)
|
29
|
+
file_path = path_to_release_table_file(domain_id, data_product_id, segment_id)
|
30
|
+
data = GoodData::Helpers::Csv.read_as_hash(file_path)
|
31
|
+
latest_master_project = data.sort_by { |master| master[:version] }
|
31
32
|
.reverse.first
|
33
|
+
|
34
|
+
version_info = latest_master_project ? "master_pid=#{latest_master_project[:master_project_id]} version=#{latest_master_project[:version]}" : ""
|
35
|
+
GoodData.gd_logger.info "Getting latest master project: file=#{file_path} domain=#{domain_id} data_product=#{data_product_id} segment=#{segment_id} #{version_info}"
|
36
|
+
latest_master_project
|
32
37
|
end
|
33
38
|
|
34
|
-
def update_latest_master_to_nfs(domain_id, segment_id, master_pid, version)
|
39
|
+
def update_latest_master_to_nfs(domain_id, data_product_id, segment_id, master_pid, version)
|
40
|
+
file_path = path_to_release_table_file(domain_id, data_product_id, segment_id)
|
41
|
+
GoodData.gd_logger.info "Updating release table: file=#{file_path} domain=#{domain_id} data_product=#{data_product_id} segment=#{segment_id} master_pid=#{master_pid} version=#{version}" # rubocop:disable Metrics/LineLength
|
35
42
|
GoodData::Helpers::Csv.ammend_line(
|
36
|
-
|
43
|
+
file_path,
|
37
44
|
master_project_id: master_pid,
|
38
45
|
version: version
|
39
46
|
)
|
40
47
|
end
|
41
48
|
|
42
|
-
def path_to_release_table_file(domain_id, segment_id)
|
43
|
-
|
49
|
+
def path_to_release_table_file(domain_id, data_prod_id, segment_id)
|
50
|
+
nsf_directory = ENV['RELEASE_TABLE_NFS_DIRECTORY'] || DEFAULT_NFS_DIRECTORY
|
51
|
+
[nsf_directory, domain_id, data_prod_id + '-' + segment_id + '.csv'].join('/')
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
data/lib/gooddata/lcm/lcm2.rb
CHANGED
@@ -18,6 +18,7 @@ require 'active_support/core_ext/hash/compact'
|
|
18
18
|
require_relative 'actions/actions'
|
19
19
|
require_relative 'dsl/dsl'
|
20
20
|
require_relative 'helpers/helpers'
|
21
|
+
require_relative 'exceptions/lcm_execution_error'
|
21
22
|
|
22
23
|
using TrueExtensions
|
23
24
|
using FalseExtensions
|
@@ -105,6 +106,14 @@ module GoodData
|
|
105
106
|
UpdateReleaseTable
|
106
107
|
],
|
107
108
|
|
109
|
+
release_set_master_project: [
|
110
|
+
EnsureReleaseTable,
|
111
|
+
CollectDataProduct,
|
112
|
+
SegmentsFilter,
|
113
|
+
SetMasterProject,
|
114
|
+
UpdateReleaseTable
|
115
|
+
],
|
116
|
+
|
108
117
|
provision: [
|
109
118
|
EnsureReleaseTable,
|
110
119
|
CollectDataProduct,
|
@@ -129,6 +138,7 @@ module GoodData
|
|
129
138
|
EnsureTechnicalUsersDomain,
|
130
139
|
EnsureTechnicalUsersProject,
|
131
140
|
SynchronizeLdm,
|
141
|
+
MigrateGdcDateDimension,
|
132
142
|
SynchronizeClients,
|
133
143
|
SynchronizeComputedAttributes,
|
134
144
|
CollectDymanicScheduleParams,
|
@@ -270,8 +280,14 @@ module GoodData
|
|
270
280
|
|
271
281
|
GoodData.gd_logger.brick = mode
|
272
282
|
|
283
|
+
final_mode = if params.set_master_project && mode == 'release'
|
284
|
+
'release_set_master_project'
|
285
|
+
else
|
286
|
+
mode
|
287
|
+
end
|
288
|
+
|
273
289
|
# Get actions for mode specified
|
274
|
-
actions = get_mode_actions(
|
290
|
+
actions = get_mode_actions(final_mode)
|
275
291
|
|
276
292
|
if params.actions
|
277
293
|
actions = params.actions.map do |action|
|
@@ -304,6 +320,12 @@ module GoodData
|
|
304
320
|
skip_actions.include?(action.name.split('::').last)
|
305
321
|
end
|
306
322
|
|
323
|
+
sync_mode = params.fetch(:sync_mode, nil)
|
324
|
+
if mode == 'users' && %w[add_to_organization remove_from_organization].include?(sync_mode)
|
325
|
+
actions = actions.reject do |action|
|
326
|
+
%w[CollectDataProduct CollectSegments].include?(action.name.split('::').last)
|
327
|
+
end
|
328
|
+
end
|
307
329
|
check_unused_params(actions, params)
|
308
330
|
print_action_names(mode, actions)
|
309
331
|
|
@@ -357,10 +379,11 @@ module GoodData
|
|
357
379
|
|
358
380
|
if errors.any?
|
359
381
|
error_message = JSON.pretty_generate(errors)
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
382
|
+
if strict_mode
|
383
|
+
raise GoodData::LcmExecutionError.new(errors[0][:err], error_message)
|
384
|
+
else
|
385
|
+
GoodData.logger.error(error_message)
|
386
|
+
end
|
364
387
|
end
|
365
388
|
|
366
389
|
result
|
@@ -222,24 +222,26 @@ module GoodData
|
|
222
222
|
domain = client.domain(domain)
|
223
223
|
if id == :all
|
224
224
|
GoodData.logger.warn("Retrieving all users from domain #{domain.name}")
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
end
|
232
|
-
|
233
|
-
tmp['accountSettings']['items'].each do |user_data|
|
234
|
-
user = client.create(GoodData::Profile, user_data)
|
235
|
-
y << user if user
|
236
|
-
end
|
237
|
-
break if tmp['accountSettings']['items'].count < page_limit
|
238
|
-
offset += page_limit
|
225
|
+
all_users = []
|
226
|
+
page_limit = opts[:page_limit] || 1000
|
227
|
+
offset = opts[:offset] || 0
|
228
|
+
loop do
|
229
|
+
begin
|
230
|
+
tmp = client(opts).get("#{domain.uri}/users", params: { offset: offset, limit: page_limit })
|
239
231
|
end
|
232
|
+
|
233
|
+
tmp['accountSettings']['items'].each do |user_data|
|
234
|
+
user = client.create(GoodData::Profile, user_data)
|
235
|
+
all_users << user if user
|
236
|
+
end
|
237
|
+
break if tmp['accountSettings']['items'].count < page_limit
|
238
|
+
|
239
|
+
offset += page_limit
|
240
240
|
end
|
241
|
+
|
242
|
+
all_users
|
241
243
|
else
|
242
|
-
find_user_by_login(domain, id)
|
244
|
+
find_user_by_login(domain, id, opts)
|
243
245
|
end
|
244
246
|
end
|
245
247
|
|
@@ -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?
|