gooddata 2.1.7-java → 2.1.12-java

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gdc-ii-config.yaml +3 -0
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +2 -4
  5. data/CHANGELOG.md +39 -0
  6. data/Dockerfile +17 -4
  7. data/Dockerfile.jruby +4 -4
  8. data/Dockerfile.ruby +5 -4
  9. data/SDK_VERSION +1 -1
  10. data/VERSION +1 -1
  11. data/bin/provision.sh +2 -0
  12. data/bin/release.sh +2 -0
  13. data/bin/rollout.sh +2 -0
  14. data/bin/run_brick.rb +31 -7
  15. data/bin/test_projects_cleanup.rb +10 -2
  16. data/bin/user_filters.sh +2 -0
  17. data/ci.rake +1 -1
  18. data/ci/bigquery/pom.xml +54 -0
  19. data/ci/redshift/pom.xml +73 -0
  20. data/ci/snowflake/pom.xml +57 -0
  21. data/dev-gooddata-sso.pub.encrypted +40 -40
  22. data/gdc_fossa_lcm.yaml +2 -0
  23. data/gdc_fossa_ruby_sdk.yaml +4 -0
  24. data/gooddata.gemspec +7 -3
  25. data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
  26. data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +22 -12
  27. data/lcm.rake +14 -0
  28. data/lib/gooddata/bricks/middleware/execution_result_middleware.rb +68 -0
  29. data/lib/gooddata/bricks/middleware/logger_middleware.rb +2 -1
  30. data/lib/gooddata/bricks/middleware/mask_logger_decorator.rb +5 -1
  31. data/lib/gooddata/bricks/pipeline.rb +7 -0
  32. data/lib/gooddata/cloud_resources/bigquery/bigquery_client.rb +86 -0
  33. data/lib/gooddata/cloud_resources/bigquery/drivers/.gitkeepme +0 -0
  34. data/lib/gooddata/cloud_resources/cloud_resouce_factory.rb +28 -0
  35. data/lib/gooddata/cloud_resources/cloud_resource_client.rb +24 -0
  36. data/lib/gooddata/cloud_resources/cloud_resources.rb +12 -0
  37. data/lib/gooddata/cloud_resources/redshift/drivers/log4j.properties +15 -0
  38. data/lib/gooddata/cloud_resources/redshift/redshift_client.rb +101 -0
  39. data/lib/gooddata/cloud_resources/snowflake/drivers/.gitkeepme +0 -0
  40. data/lib/gooddata/cloud_resources/snowflake/snowflake_client.rb +84 -0
  41. data/lib/gooddata/exceptions/invalid_env_error.rb +15 -0
  42. data/lib/gooddata/helpers/data_helper.rb +10 -0
  43. data/lib/gooddata/helpers/global_helpers.rb +4 -0
  44. data/lib/gooddata/helpers/global_helpers_params.rb +4 -7
  45. data/lib/gooddata/lcm/actions/collect_clients.rb +6 -6
  46. data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +6 -6
  47. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +4 -1
  48. data/lib/gooddata/lcm/actions/collect_segments.rb +1 -2
  49. data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +7 -6
  50. data/lib/gooddata/lcm/actions/create_segment_masters.rb +5 -3
  51. data/lib/gooddata/lcm/actions/set_master_project.rb +76 -0
  52. data/lib/gooddata/lcm/actions/synchronize_clients.rb +1 -1
  53. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +1 -2
  54. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +17 -2
  55. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +23 -3
  56. data/lib/gooddata/lcm/actions/synchronize_users.rb +50 -30
  57. data/lib/gooddata/lcm/actions/update_release_table.rb +7 -1
  58. data/lib/gooddata/lcm/exceptions/lcm_execution_error.rb +16 -0
  59. data/lib/gooddata/lcm/helpers/release_table_helper.rb +16 -8
  60. data/lib/gooddata/lcm/lcm2.rb +27 -5
  61. data/lib/gooddata/models/domain.rb +17 -15
  62. data/lib/gooddata/models/execution.rb +0 -1
  63. data/lib/gooddata/models/execution_detail.rb +0 -1
  64. data/lib/gooddata/models/profile.rb +33 -11
  65. data/lib/gooddata/models/project.rb +45 -25
  66. data/lib/gooddata/models/project_creator.rb +2 -0
  67. data/lib/gooddata/models/schedule.rb +0 -1
  68. data/lib/gooddata/rest/client.rb +2 -2
  69. data/lib/gooddata/rest/connection.rb +5 -3
  70. data/rubydev_public.gpg.encrypted +51 -51
  71. data/rubydev_secret_keys.gpg.encrypted +109 -109
  72. metadata +38 -15
  73. data/lib/gooddata/extensions/hash.rb +0 -18
@@ -71,7 +71,7 @@ module GoodData
71
71
  ads_output_stage_prefix = segment_in.ads_output_stage_prefix
72
72
 
73
73
  # Create master project Postgres
74
- version = get_project_version(params, domain_name, segment_id) + 1
74
+ version = get_project_version(params, domain_name, data_product, segment_id) + 1
75
75
 
76
76
  master_name = segment_in.master_name.gsub('#{version}', version.to_s)
77
77
 
@@ -113,6 +113,7 @@ module GoodData
113
113
  status = 'modified'
114
114
  end
115
115
 
116
+ segment_in[:data_product_id] = data_product.data_product_id
116
117
  segment_in[:master_pid] = project.pid
117
118
  segment_in[:version] = version
118
119
  segment_in[:timestamp] = Time.now.utc.iso8601
@@ -150,7 +151,7 @@ module GoodData
150
151
  }
151
152
  end
152
153
 
153
- def get_project_version(params, domain_name, segment_id)
154
+ def get_project_version(params, domain_name, data_product, segment_id)
154
155
  if params.ads_client
155
156
  current_master = GoodData::LCM2::Helpers.latest_master_project_from_ads(
156
157
  params.release_table_name,
@@ -158,7 +159,8 @@ module GoodData
158
159
  segment_id
159
160
  )
160
161
  else
161
- current_master = GoodData::LCM2::Helpers.latest_master_project_from_nfs(domain_name, segment_id)
162
+ data_product_id = data_product.data_product_id # data_product was populated by CollectDataProduct action already
163
+ current_master = GoodData::LCM2::Helpers.latest_master_project_from_nfs(domain_name, data_product_id, segment_id)
162
164
  end
163
165
  return 0 unless current_master
164
166
  current_master[:version].to_i
@@ -0,0 +1,76 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Copyright (c) 2010-2017 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_relative 'base_action'
9
+
10
+ module GoodData
11
+ module LCM2
12
+ class SetMasterProject < BaseAction
13
+ DESCRIPTION = 'Set master project'
14
+
15
+ PARAMS = define_params(self) do
16
+ description 'Organization Name'
17
+ param :organization, instance_of(Type::StringType), required: false
18
+
19
+ description 'Domain'
20
+ param :domain, instance_of(Type::StringType), required: false
21
+
22
+ description 'ADS Client'
23
+ param :ads_client, instance_of(Type::AdsClientType), required: false
24
+
25
+ description 'Table Name'
26
+ param :release_table_name, instance_of(Type::StringType), required: false
27
+
28
+ description 'Segments to manage'
29
+ param :segments, array_of(instance_of(Type::SegmentType)), required: true
30
+
31
+ description 'DataProduct to manage'
32
+ param :data_product, instance_of(Type::GDDataProductType), required: false
33
+
34
+ description 'Released master project should be used in next rollout'
35
+ param :set_master_project, instance_of(Type::StringType), required: false
36
+ end
37
+
38
+ class << self
39
+ def call(params)
40
+ results = []
41
+ domain_name = params.organization || params.domain
42
+ data_product = params.data_product
43
+ params.segments.each do |segment_in|
44
+ version = get_latest_version(params, domain_name, data_product.data_product_id, segment_in.segment_id) + 1
45
+ segment_in[:data_product_id] = data_product.data_product_id
46
+ segment_in[:master_pid] = params.set_master_project
47
+ segment_in[:version] = version
48
+ segment_in[:timestamp] = Time.now.utc.iso8601
49
+
50
+ results << {
51
+ data_product_id: data_product.data_product_id,
52
+ segment_id: segment_in.segment_id,
53
+ version: version
54
+ }
55
+ end
56
+ results
57
+ end
58
+
59
+ def get_latest_version(params, domain_name, data_product_id, segment_id)
60
+ if params.ads_client
61
+ current_master = GoodData::LCM2::Helpers.latest_master_project_from_ads(
62
+ params.release_table_name,
63
+ params.ads_client,
64
+ segment_id
65
+ )
66
+ else
67
+ current_master = GoodData::LCM2::Helpers.latest_master_project_from_nfs(domain_name, data_product_id, segment_id)
68
+ end
69
+ return 0 unless current_master
70
+
71
+ current_master[:version].to_i
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -68,7 +68,7 @@ module GoodData
68
68
  segment.segment_id
69
69
  )
70
70
  else
71
- current_master = GoodData::LCM2::Helpers.latest_master_project_from_nfs(domain_name, segment.segment_id)
71
+ current_master = GoodData::LCM2::Helpers.latest_master_project_from_nfs(domain_name, data_product.data_product_id, segment.segment_id)
72
72
  end
73
73
 
74
74
  # TODO: Check res.first.nil? || res.first[:master_project_id].nil?
@@ -80,8 +80,7 @@ module GoodData
80
80
  res = GoodData::Helpers.symbolize_keys(res)
81
81
 
82
82
  if res[:syncedResult][:errors]
83
- params.gdc_logger.error "Error: #{res[:syncedResult][:errors].pretty_inspect}"
84
- fail "Failed to sync processes/schedules for segment #{segment_id}"
83
+ fail "Failed to sync processes/schedules for segment #{segment_id}. Error: #{res[:syncedResult][:errors].pretty_inspect}"
85
84
  end
86
85
 
87
86
  if res[:syncedResult][:clients]
@@ -44,6 +44,9 @@ module GoodData
44
44
 
45
45
  description 'Specifies how to synchronize LDM and resolve possible conflicts'
46
46
  param :synchronize_ldm, instance_of(Type::SynchronizeLDM), required: false, default: 'diff_against_master_with_fallback'
47
+
48
+ description 'Enables handling of deprecated objects in the logical data model.'
49
+ param :include_deprecated, instance_of(Type::BooleanType), required: false, default: false
47
50
  end
48
51
 
49
52
  class << self
@@ -70,6 +73,7 @@ module GoodData
70
73
  results = []
71
74
  client = params.gdc_gd_client
72
75
  exclude_fact_rule = params.exclude_fact_rule.to_b
76
+ include_deprecated = params.include_deprecated.to_b
73
77
  from_pid = segment_info[:from]
74
78
  from = params.development_client.projects(from_pid) || fail("Invalid 'from' project specified - '#{from_pid}'")
75
79
 
@@ -79,10 +83,19 @@ module GoodData
79
83
  previous_master = segment_info[:previous_master]
80
84
  diff_against_master = %w(diff_against_master_with_fallback diff_against_master)
81
85
  .include?(params[:synchronize_ldm].downcase)
86
+ GoodData.logger.info "Synchronize LDM mode: '#{params[:synchronize_ldm].downcase}'"
82
87
  if previous_master && diff_against_master
83
88
  maql_diff_params = [:includeGrain]
84
89
  maql_diff_params << :excludeFactRule if exclude_fact_rule
90
+ maql_diff_params << :includeDeprecated if include_deprecated
85
91
  maql_diff = previous_master.maql_diff(blueprint: blueprint, params: maql_diff_params)
92
+ chunks = maql_diff['projectModelDiff']['updateScripts']
93
+ if chunks.empty?
94
+ GoodData.logger.info "Synchronize LDM to clients will not proceed in mode \
95
+ '#{params[:synchronize_ldm].downcase}' due to no LDM changes in the new master project. \
96
+ If you had changed LDM of clients manually, please use mode 'diff_against_clients' \
97
+ to force synchronize LDM to clients"
98
+ end
86
99
  end
87
100
 
88
101
  segment_info[:to] = segment_info[:to].pmap do |entry|
@@ -96,7 +109,8 @@ module GoodData
96
109
  update_preference: params[:update_preference],
97
110
  exclude_fact_rule: exclude_fact_rule,
98
111
  execute_ca_scripts: false,
99
- maql_diff: maql_diff
112
+ maql_diff: maql_diff,
113
+ include_deprecated: include_deprecated
100
114
  )
101
115
  rescue MaqlExecutionError => e
102
116
  GoodData.logger.info("Applying MAQL to project #{to_project.title} - #{pid} failed. Reason: #{e}")
@@ -106,7 +120,8 @@ module GoodData
106
120
  blueprint,
107
121
  update_preference: params[:update_preference],
108
122
  exclude_fact_rule: exclude_fact_rule,
109
- execute_ca_scripts: false
123
+ execute_ca_scripts: false,
124
+ include_deprecated: include_deprecated
110
125
  )
111
126
  end
112
127
 
@@ -121,6 +121,7 @@ module GoodData
121
121
  users_brick_input: params.users_brick_users
122
122
  }
123
123
  all_clients = domain.clients(:all, data_product).to_a
124
+ GoodData.gd_logger.info("Synchronizing in mode=#{mode}, number_of_clients=#{all_clients.size}, data_rows=#{user_filters.size}")
124
125
 
125
126
  GoodData.logger.info("Synchronizing in mode \"#{mode}\"")
126
127
  case mode
@@ -131,6 +132,8 @@ module GoodData
131
132
  filter = UserBricksHelper.resolve_client_id(domain, project, params.data_product)
132
133
  end
133
134
  user_filters = user_filters.select { |f| f[:pid] == filter } if filter
135
+
136
+ GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{project.pid}, data_rows=#{user_filters.size}")
134
137
  sync_user_filters(project, user_filters, run_params, symbolized_config)
135
138
  when 'sync_multiple_projects_based_on_pid', 'sync_multiple_projects_based_on_custom_id'
136
139
  users_by_project = run_params[:users_brick_input].group_by { |u| u[:pid] }
@@ -144,6 +147,8 @@ module GoodData
144
147
  elsif mode == 'sync_multiple_projects_based_on_pid'
145
148
  current_project = client.projects(id)
146
149
  end
150
+
151
+ GoodData.gd_logger.info("Synchronizing in mode=#{mode}, project_id=#{id}, data_rows=#{new_filters.size}")
147
152
  sync_user_filters(current_project, new_filters, run_params.merge(users_brick_input: users), symbolized_config)
148
153
  end
149
154
  when 'sync_domain_client_workspaces'
@@ -170,6 +175,8 @@ module GoodData
170
175
  fail "Client #{client_id} does not have project." unless current_project
171
176
 
172
177
  working_client_ids << client_id
178
+
179
+ GoodData.gd_logger.info("Synchronizing in mode=#{mode}, client_id=#{client_id}, data_rows=#{new_filters.size}")
173
180
  partial_results = sync_user_filters(current_project, new_filters, run_params.merge(users_brick_input: users), symbolized_config)
174
181
  results.concat(partial_results[:results])
175
182
  end
@@ -182,6 +189,8 @@ module GoodData
182
189
  current_project = c.project
183
190
  users = users_by_project[c.client_id]
184
191
  params.gdc_logger.info "Delete all filters in project #{current_project.pid} of client #{c.client_id}"
192
+
193
+ GoodData.gd_logger.info("Delete all filters in project_id=#{current_project.pid}, client_id=#{c.client_id}")
185
194
  current_results = sync_user_filters(current_project, [], run_params.merge(users_brick_input: users), symbolized_config)
186
195
 
187
196
  results.concat(current_results[:results])
@@ -214,10 +223,21 @@ module GoodData
214
223
  multiple_projects_column = params.multiple_projects_column
215
224
  data_source = GoodData::Helpers::DataSource.new(params.input_source)
216
225
 
217
- without_check(PARAMS, params) do
218
- CSV.foreach(File.open(data_source.realize(params), 'r:UTF-8'), headers: csv_with_headers, return_headers: false, encoding: 'utf-8') do |row|
219
- filters << row.to_hash.merge(pid: row[multiple_projects_column])
226
+ tmp = without_check(PARAMS, params) do
227
+ File.open(data_source.realize(params), 'r:UTF-8')
228
+ end
229
+
230
+ begin
231
+ GoodData.logger.info('Start reading data')
232
+ row_count = 0
233
+ CSV.foreach(tmp, :headers => csv_with_headers, :return_headers => false, :header_converters => :downcase, :encoding => 'utf-8') do |row|
234
+ filters << row.to_hash.merge(pid: row[multiple_projects_column.downcase])
235
+ row_count += 1
236
+ GoodData.logger.info("Read #{row_count} rows") if (row_count % 50_000).zero?
220
237
  end
238
+ GoodData.logger.info("Done reading data, total #{row_count} rows")
239
+ rescue Exception => e # rubocop:disable RescueException
240
+ fail "There was an error during loading data. Message: #{e.message}. Error: #{e}"
221
241
  end
222
242
 
223
243
  if filters.empty? && %w(sync_multiple_projects_based_on_pid sync_multiple_projects_based_on_custom_id).include?(params.sync_mode)
@@ -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
- dwh = params.ads_client
351
- if dwh
352
- data = dwh.execute_select(params.input_source.query)
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
- begin
359
- data = read_csv_file(tmp)
360
- rescue Exception => e # rubocop:disable RescueException
361
- fail "There was an error during loading users from csv file. Message: #{e.message}. Error: #{e}"
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 => row[login_column] || row[login_column.to_sym],
405
+ :login => user_login,
386
406
  :password => row[password_column] || row[password_column.to_sym],
387
- :email => row[email_column] || row[login_column] || row[email_column.to_sym] || row[login_column.to_sym],
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
- GoodData::LCM2::Helpers.update_latest_master_to_nfs(domain_id, placeholders[:segment_id], placeholders[:master_project_id], placeholders[:version])
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