gooddata 2.1.12-java → 2.1.19-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/.sonar.settings +4 -0
- data/.travis.yml +78 -12
- data/CHANGELOG.md +37 -0
- data/Dockerfile +9 -3
- data/Dockerfile.jruby +11 -1
- data/LICENSE +4418 -17
- 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/test_projects_cleanup.rb +45 -3
- data/ci/postgresql/pom.xml +57 -0
- data/dev-gooddata-sso.pub.encrypted +40 -40
- data/docker-compose.lcm.yml +3 -0
- data/gdc_fossa_ruby_sdk.yaml +1 -0
- data/gooddata.gemspec +8 -5
- data/k8s/charts/lcm-bricks/Chart.yaml +1 -1
- data/k8s/charts/lcm-bricks/templates/prometheus/alertingRules.yaml +11 -1
- data/lcm.rake +10 -4
- 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/associate_clients.rb +8 -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/provision_clients.rb +31 -10
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +3 -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 +3 -2
- data/lib/gooddata/models/from_wire.rb +1 -0
- data/lib/gooddata/models/metadata/analytical_dashboard.rb +49 -0
- data/lib/gooddata/models/metadata/analytical_visualization_object.rb +30 -0
- data/lib/gooddata/models/metadata/scheduled_mail.rb +1 -1
- data/lib/gooddata/models/metadata/visualization_object.rb +50 -0
- data/lib/gooddata/models/process.rb +11 -3
- data/lib/gooddata/models/project.rb +104 -13
- 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/lib/gooddata/rest/phmap.rb +1 -1
- data/rubydev_public.gpg.encrypted +51 -51
- data/rubydev_secret_keys.gpg.encrypted +109 -109
- metadata +20 -20
- data/DEPENDENCIES.md +0 -880
@@ -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
|
@@ -43,7 +43,7 @@ module GoodData
|
|
43
43
|
RESULT_HEADER = [
|
44
44
|
:id,
|
45
45
|
:status,
|
46
|
-
:
|
46
|
+
:project,
|
47
47
|
:client,
|
48
48
|
:type
|
49
49
|
]
|
@@ -102,7 +102,13 @@ module GoodData
|
|
102
102
|
options = { delete_projects: delete_projects }
|
103
103
|
options.merge!(delete_extra_option(params, delete_extra)) if delete_extra
|
104
104
|
|
105
|
-
domain.update_clients(params.clients, options)
|
105
|
+
results = domain.update_clients(params.clients, options)
|
106
|
+
# Update status to CREATED if the client has no project
|
107
|
+
results&.each do |r|
|
108
|
+
r[:status] = 'CREATED' if r[:originalProject].nil?
|
109
|
+
r[:project] = r[:originalProject]
|
110
|
+
end
|
111
|
+
results
|
106
112
|
end
|
107
113
|
|
108
114
|
private
|
@@ -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'
|
@@ -50,7 +50,8 @@ module GoodData
|
|
50
50
|
if transfer_all
|
51
51
|
vizs = MdObject.query('visualizationObject', MdObject, client: development_client, project: from_project)
|
52
52
|
viz_widgets = MdObject.query('visualizationWidget', MdObject, client: development_client, project: from_project)
|
53
|
-
|
53
|
+
theme = MdObject.query('theme', MdObject, client: development_client, project: from_project)
|
54
|
+
objects = (from_project.reports.to_a + from_project.metrics.to_a + from_project.variables.to_a + vizs.to_a + viz_widgets.to_a + theme.to_a).map(&:uri)
|
54
55
|
elsif production_tags.any?
|
55
56
|
objects = from_project.find_by_tag(production_tags)
|
56
57
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# (C) 2019-2020 GoodData Corporation
|
3
|
+
require_relative 'base_action'
|
4
|
+
|
5
|
+
# Migrate date dimension urn:gooddata:date or urn:custom:date to urn:custom_v2:date
|
6
|
+
module GoodData
|
7
|
+
module LCM2
|
8
|
+
class MigrateGdcDateDimension < BaseAction
|
9
|
+
DESCRIPTION = 'Migrate Gdc Date Dimension'
|
10
|
+
DATE_DIMENSION_CUSTOM_V2 = 'urn:custom_v2:date'
|
11
|
+
DATE_DIMENSION_OLD = %w[urn:gooddata:date urn:custom:date]
|
12
|
+
|
13
|
+
PARAMS = define_params(self) do
|
14
|
+
description 'Client Used for Connecting to GD'
|
15
|
+
param :gdc_gd_client, instance_of(Type::GdClientType), required: true
|
16
|
+
|
17
|
+
description 'Specifies how to synchronize LDM and resolve possible conflicts'
|
18
|
+
param :synchronize_ldm, instance_of(Type::SynchronizeLDM), required: false, default: 'diff_against_master_with_fallback'
|
19
|
+
|
20
|
+
description 'Synchronization Info'
|
21
|
+
param :synchronize, array_of(instance_of(Type::SynchronizationInfoType)), required: true, generated: true
|
22
|
+
end
|
23
|
+
|
24
|
+
RESULT_HEADER = %i[from to status]
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def call(params)
|
28
|
+
results = []
|
29
|
+
params.synchronize.map do |segment_info|
|
30
|
+
result = migrate_date_dimension(params, segment_info)
|
31
|
+
results.concat(result)
|
32
|
+
end
|
33
|
+
|
34
|
+
{
|
35
|
+
results: results
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def migrate_date_dimension(params, segment_info)
|
40
|
+
results = []
|
41
|
+
client = params.gdc_gd_client
|
42
|
+
latest_blueprint = segment_info[:from_blueprint]
|
43
|
+
# don't migrate when latest master doesn't contain custom v2 date.
|
44
|
+
return results unless contain_v2?(latest_blueprint)
|
45
|
+
|
46
|
+
previous_blueprint = segment_info[:previous_master]&.blueprint
|
47
|
+
# check latest master and previous master
|
48
|
+
master_upgrade_datasets = get_upgrade_dates(latest_blueprint, previous_blueprint) if params[:synchronize_ldm].downcase == 'diff_against_master' && previous_blueprint
|
49
|
+
unless master_upgrade_datasets&.empty?
|
50
|
+
segment_info[:to].pmap do |entry|
|
51
|
+
pid = entry[:pid]
|
52
|
+
to_project = client.projects(pid) || fail("Invalid 'to' project specified - '#{pid}'")
|
53
|
+
to_blueprint = to_project.blueprint
|
54
|
+
upgrade_datasets = get_upgrade_dates(latest_blueprint, to_blueprint)
|
55
|
+
next if upgrade_datasets.empty?
|
56
|
+
|
57
|
+
message = get_upgrade_message(upgrade_datasets)
|
58
|
+
|
59
|
+
results << {
|
60
|
+
from: segment_info[:from],
|
61
|
+
to: pid,
|
62
|
+
status: to_project.upgrade_custom_v2(message)
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
results
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_upgrade_dates(src_blueprint, dest_blueprint)
|
71
|
+
dest_dates = get_date_dimensions(dest_blueprint) if dest_blueprint
|
72
|
+
src_dates = get_date_dimensions(src_blueprint) if src_blueprint
|
73
|
+
|
74
|
+
return false if dest_dates.empty? || src_dates.empty?
|
75
|
+
|
76
|
+
upgrade_datasets = []
|
77
|
+
dest_dates.each do |dest|
|
78
|
+
src_dim = get_date_dimension(src_blueprint, dest[:id])
|
79
|
+
next unless src_dim
|
80
|
+
|
81
|
+
upgrade_datasets << src_dim[:identifier] if upgrade?(src_dim, dest) && src_dim[:identifier]
|
82
|
+
end
|
83
|
+
|
84
|
+
upgrade_datasets
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_upgrade_message(upgrade_datasets)
|
88
|
+
{
|
89
|
+
upgrade: {
|
90
|
+
dateDatasets: {
|
91
|
+
upgrade: "exact",
|
92
|
+
datasets: upgrade_datasets
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def upgrade?(src_dim, dest_dim)
|
99
|
+
src_dim[:urn] == DATE_DIMENSION_CUSTOM_V2 && DATE_DIMENSION_OLD.any? { |e| dest_dim[:urn] == e }
|
100
|
+
end
|
101
|
+
|
102
|
+
def contain_v2?(blueprint)
|
103
|
+
get_date_dimensions(blueprint).any? { |e| e[:urn] == DATE_DIMENSION_CUSTOM_V2 }
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_date_dimension(blueprint, id)
|
107
|
+
GoodData::Model::ProjectBlueprint.find_date_dimension(blueprint, id)
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_date_dimensions(blueprint)
|
111
|
+
GoodData::Model::ProjectBlueprint.date_dimensions(blueprint)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -48,7 +48,8 @@ module GoodData
|
|
48
48
|
domain_name = params.organization || params.domain
|
49
49
|
fail "Either organisation or domain has to be specified in params" unless domain_name
|
50
50
|
domain = client.domain(domain_name) || fail("Invalid domain name specified - #{domain_name}")
|
51
|
-
|
51
|
+
error_message = nil
|
52
|
+
invalid_client_ids = []
|
52
53
|
begin
|
53
54
|
results = params.segments.map do |segment|
|
54
55
|
segment_object = domain.segments(segment.segment_id, data_product)
|
@@ -57,33 +58,53 @@ module GoodData
|
|
57
58
|
end
|
58
59
|
|
59
60
|
unless tmp.empty?
|
60
|
-
|
61
|
+
synchronize_project = {
|
61
62
|
segment_id: segment.segment_id,
|
62
63
|
from: segment.development_pid,
|
63
64
|
to: tmp.map do |entry|
|
64
65
|
unless entry[:project_uri]
|
65
|
-
|
66
|
+
error_message = "There was error during provisioning clients: #{entry[:error]}" unless error_message
|
67
|
+
invalid_client_ids << entry[:id]
|
68
|
+
next
|
66
69
|
end
|
67
70
|
{
|
68
71
|
pid: entry[:project_uri].split('/').last,
|
69
72
|
client_id: entry[:id]
|
70
73
|
}
|
71
|
-
end
|
74
|
+
end.compact
|
72
75
|
}
|
76
|
+
|
77
|
+
synchronize_projects << synchronize_project unless synchronize_project[:to].empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
if error_message
|
81
|
+
params.gdc_logger.debug "#{error_message}. Purge all invalid clients now ..."
|
82
|
+
deleted_client_ids = []
|
83
|
+
|
84
|
+
segment_object.clients.map do |segment_client|
|
85
|
+
project = segment_client.project
|
86
|
+
if (project.nil? || project.deleted?)
|
87
|
+
client_id = segment_client.client_id
|
88
|
+
if invalid_client_ids.include?(client_id)
|
89
|
+
segment_client.delete
|
90
|
+
deleted_client_ids << client_id
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
params.gdc_logger.debug "Deleted clients: #{deleted_client_ids.join(', ')}"
|
96
|
+
raise error_message unless error_message['TooManyProjectsCreatedException'] || error_message['Max number registered projects']
|
97
|
+
break tmp
|
73
98
|
end
|
74
99
|
|
75
100
|
tmp
|
76
101
|
end
|
77
102
|
rescue => e
|
78
|
-
params.gdc_logger.error "Problem occurs when provisioning clients.
|
79
|
-
res = LCM2.run_action PurgeClients, params
|
80
|
-
params.gdc_logger.debug "Purge clients result: #{res}"
|
81
|
-
deleted_client_ids = res[:results].select { |r| r[:status] == 'purged' }.map { |r| r[:client_id] }
|
82
|
-
params.gdc_logger.error "Deleted clients: #{deleted_client_ids.join(', ')}"
|
103
|
+
params.gdc_logger.error "Problem occurs when provisioning clients."
|
83
104
|
raise e
|
84
105
|
end
|
85
106
|
|
86
|
-
results.flatten!
|
107
|
+
results.flatten! if results
|
87
108
|
|
88
109
|
# Return results
|
89
110
|
{
|
@@ -49,6 +49,8 @@ module GoodData
|
|
49
49
|
param :include_deprecated, instance_of(Type::BooleanType), required: false, default: false
|
50
50
|
end
|
51
51
|
|
52
|
+
RESULT_HEADER = %i[from to status]
|
53
|
+
|
52
54
|
class << self
|
53
55
|
def call(params)
|
54
56
|
results = []
|
@@ -76,9 +78,9 @@ module GoodData
|
|
76
78
|
include_deprecated = params.include_deprecated.to_b
|
77
79
|
from_pid = segment_info[:from]
|
78
80
|
from = params.development_client.projects(from_pid) || fail("Invalid 'from' project specified - '#{from_pid}'")
|
79
|
-
|
80
81
|
GoodData.logger.info "Creating Blueprint, project: '#{from.title}', PID: #{from_pid}"
|
81
82
|
blueprint = from.blueprint(include_ca: params.include_computed_attributes.to_b)
|
83
|
+
segment_info[:from_blueprint] = blueprint
|
82
84
|
maql_diff = nil
|
83
85
|
previous_master = segment_info[:previous_master]
|
84
86
|
diff_against_master = %w(diff_against_master_with_fallback diff_against_master)
|
@@ -167,6 +167,10 @@ module GoodData
|
|
167
167
|
fail "Client id cannot be empty" if client_id.blank?
|
168
168
|
|
169
169
|
c = all_clients.detect { |specific_client| specific_client.id == client_id }
|
170
|
+
if c.nil?
|
171
|
+
params.gdc_logger.warn "Client #{client_id} is not found"
|
172
|
+
next
|
173
|
+
end
|
170
174
|
if params.segments && !segment_uris.include?(c.segment_uri)
|
171
175
|
params.gdc_logger.warn "Client #{client_id} is outside segments_filter #{params.segments}"
|
172
176
|
next
|
@@ -182,11 +182,11 @@ module GoodData
|
|
182
182
|
# value of a project id in the data since he does not know it upfront
|
183
183
|
# and we cannot influence its value.
|
184
184
|
common_params = {
|
185
|
-
domain: domain,
|
186
|
-
whitelists: whitelists,
|
187
|
-
ignore_failures: ignore_failures,
|
188
|
-
remove_users_from_project: remove_users_from_project,
|
189
|
-
do_not_touch_users_that_are_not_mentioned: do_not_touch_users_that_are_not_mentioned,
|
185
|
+
domain: domain,
|
186
|
+
whitelists: whitelists,
|
187
|
+
ignore_failures: ignore_failures,
|
188
|
+
remove_users_from_project: remove_users_from_project,
|
189
|
+
do_not_touch_users_that_are_not_mentioned: do_not_touch_users_that_are_not_mentioned,
|
190
190
|
create_non_existing_user_groups: create_non_existing_user_groups,
|
191
191
|
user_groups_cache: nil
|
192
192
|
}
|
@@ -198,7 +198,8 @@ module GoodData
|
|
198
198
|
domain.create_users(new_users.uniq { |u| u[:login] || u[:email] })
|
199
199
|
when 'remove_from_organization'
|
200
200
|
user_ids = new_users.uniq { |u| u[:login] || u[:email] }.map { |u| u[:login] || u[:email] }
|
201
|
-
users = user_ids.map { |u| domain.users(u, client: client) }
|
201
|
+
users = user_ids.map { |u| domain.users(u, client: client) }.reject(&:nil?)
|
202
|
+
params.gdc_logger.info "#{user_ids.count - users.count} users were not found (or were deleted) in domain #{domain_name}" if user_ids.count > users.count
|
202
203
|
params.gdc_logger.warn "Deleting #{users.count} users from domain #{domain_name}"
|
203
204
|
|
204
205
|
GoodData.gd_logger.info("Synchronizing in mode=#{mode}, domain=#{domain_name}, data_rows=#{users.count}")
|