gooddata 1.0.2-java → 1.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +12 -0
- data/README.md +5 -2
- data/Rakefile +0 -1
- data/dev-gooddata-sso.pub.encrypted +40 -0
- data/gooddata.gemspec +3 -3
- data/lib/gooddata/connection.rb +23 -13
- data/lib/gooddata/helpers/data_helper.rb +0 -1
- data/lib/gooddata/lcm/actions/apply_custom_maql.rb +8 -1
- data/lib/gooddata/lcm/actions/associate_clients.rb +8 -1
- data/lib/gooddata/lcm/actions/base_action.rb +10 -0
- data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +7 -1
- data/lib/gooddata/lcm/actions/collect_client_projects.rb +3 -0
- data/lib/gooddata/lcm/actions/collect_clients.rb +3 -1
- data/lib/gooddata/lcm/actions/collect_data_product.rb +10 -2
- data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +12 -1
- data/lib/gooddata/lcm/actions/collect_ldm_objects.rb +6 -2
- data/lib/gooddata/lcm/actions/collect_meta.rb +1 -1
- data/lib/gooddata/lcm/actions/collect_segment_clients.rb +8 -1
- data/lib/gooddata/lcm/actions/collect_segments.rb +6 -5
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +1 -1
- data/lib/gooddata/lcm/actions/collect_users_brick_users.rb +10 -4
- data/lib/gooddata/lcm/actions/create_segment_masters.rb +12 -2
- data/lib/gooddata/lcm/actions/ensure_data_product.rb +10 -0
- data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -1
- data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +3 -0
- data/lib/gooddata/lcm/actions/execute_schedules.rb +10 -0
- data/lib/gooddata/lcm/actions/import_object_collections.rb +1 -1
- data/lib/gooddata/lcm/actions/provision_clients.rb +12 -2
- data/lib/gooddata/lcm/actions/purge_clients.rb +2 -0
- data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +3 -0
- data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_cas.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_clients.rb +11 -1
- data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +12 -7
- data/lib/gooddata/lcm/actions/synchronize_label_types.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +18 -7
- data/lib/gooddata/lcm/actions/synchronize_meta.rb +9 -0
- data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +11 -1
- data/lib/gooddata/lcm/actions/synchronize_processes.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_schedules.rb +4 -1
- data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +6 -0
- data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +60 -15
- data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +7 -1
- data/lib/gooddata/lcm/actions/synchronize_users.rb +106 -3
- data/lib/gooddata/lcm/actions/update_release_table.rb +19 -0
- data/lib/gooddata/lcm/helpers/check_helper.rb +21 -6
- data/lib/gooddata/lcm/lcm2.rb +35 -22
- data/lib/gooddata/lcm/types/class/gd_logger.rb +23 -0
- data/lib/gooddata/lcm/types/class/gd_product.rb +23 -0
- data/lib/gooddata/lcm/types/class/gd_project.rb +23 -0
- data/lib/gooddata/lcm/types/class/smart_hash.rb +23 -0
- data/lib/gooddata/lcm/types/complex/segment.rb +1 -1
- data/lib/gooddata/lcm/types/scalar/integer.rb +2 -2
- data/lib/gooddata/lcm/types/special/any.rb +18 -0
- data/lib/gooddata/models/blueprint/dataset_blueprint.rb +1 -1
- data/lib/gooddata/models/blueprint/to_manifest.rb +1 -3
- data/lib/gooddata/models/blueprint/to_wire.rb +2 -1
- data/lib/gooddata/models/from_wire.rb +13 -1
- data/lib/gooddata/models/metadata/folder.rb +22 -0
- data/lib/gooddata/models/metadata/metric.rb +5 -8
- data/lib/gooddata/models/model.rb +1 -1
- data/lib/gooddata/models/process.rb +42 -32
- data/lib/gooddata/models/project.rb +19 -36
- data/lib/gooddata/models/project_creator.rb +3 -1
- data/lib/gooddata/models/project_role.rb +3 -4
- data/lib/gooddata/models/schedule.rb +0 -2
- data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +9 -1
- data/lib/gooddata/models/user_filters/user_filter.rb +1 -2
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -6
- data/lib/gooddata/rest/client.rb +1 -2
- data/lib/gooddata/rest/connection.rb +12 -46
- data/lib/gooddata/rest/phmap.rb +101 -56
- data/lib/gooddata/version.rb +1 -1
- data/rubydev_public.gpg.encrypted +51 -0
- data/rubydev_secret_keys.gpg.encrypted +109 -0
- data/spec/data/user_filters.csv +2 -0
- data/spec/environment/default.rb +2 -2
- data/spec/environment/development.rb +1 -1
- data/spec/environment/staging.rb +2 -3
- data/spec/environment/testing.rb +4 -4
- data/spec/integration/connection_spec.rb +37 -0
- data/spec/integration/core/connection_spec.rb +1 -1
- data/spec/integration/core/logging_spec.rb +8 -6
- data/spec/integration/core/project_spec.rb +1 -1
- data/spec/integration/mandatory_user_filter_spec.rb +53 -0
- data/spec/integration/mixins/id_to_uri_spec.rb +17 -5
- data/spec/integration/models/label_spec.rb +9 -0
- data/spec/integration/models/metric_spec.rb +24 -0
- data/spec/integration/models/process_spec.rb +35 -0
- data/spec/integration/models/project_role_spec.rb +1 -1
- data/spec/integration/models/schedule_spec.rb +0 -8
- data/spec/integration/schedule_spec.rb +4 -6
- data/spec/integration/user_filters_spec.rb +20 -16
- data/spec/integration/user_group_spec.rb +1 -1
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/can_assign_a_custom_logger.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/client_logs_when_given_custom_message.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logger/has_the_request_id_logged_when_I_passed_it.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_off/Disables_logging.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_logging/_logging_on/Enables_logging.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project/Returns_project_assigned.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_nil.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_directly.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_ID.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_project_/Assigns_project_using_project_URL.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_-_project/_with_project/Uses_project_specified.yml +354 -0
- data/spec/integration/vcr_cassettes/GoodData_Metric/all.yml +2065 -0
- data/spec/integration/vcr_cassettes/GoodData_Metric/should_be_able_to_update_folders.yml +119 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/all.yml +9812 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_get_json_containing_correct_id.yml +174 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_return_nil_for_unknown_id.yml +58 -0
- data/spec/integration/vcr_cassettes/GoodData_Mixin_MdIdToUri/should_throw_BadRequest_for_-1.yml +63 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_connect/Connects_using_username_and_password.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_disconnect/Connects_using_username_and_password.yml +299 -0
- data/spec/integration/vcr_cassettes/GoodData_Rest_Connection/_generate_request_id/Generates_a_non-empty_string.yml +2287 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_/Should_list_user_groups_as_Array.yml +56 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_add_members/Should_add_member.yml +315 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_members/Should_return_members_as_array.yml +54 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_remove_members/Should_remove_existing_members.yml +258 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_save/updates_existing_group.yml +159 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/_set_members/Should_set_new_members.yml +158 -0
- data/spec/integration/vcr_cassettes/GoodData_UserGroup/all.yml +809 -0
- data/spec/spec_helper.rb +46 -2
- data/spec/unit/actions/associate_clients_spec.rb +2 -1
- data/spec/unit/actions/collect_data_product_spec.rb +3 -1
- data/spec/unit/actions/collect_segment_clients_spec.rb +1 -0
- data/spec/unit/actions/create_segment_masters_spec.rb +1 -0
- data/spec/unit/actions/ensure_data_product_spec.rb +1 -0
- data/spec/unit/actions/ensure_technical_users_domain_spec.rb +2 -0
- data/spec/unit/actions/ensure_technical_users_project_spec.rb +4 -0
- data/spec/unit/actions/provision_clients_spec.rb +2 -1
- data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +0 -6
- data/spec/unit/actions/synchronize_ldm_spec.rb +20 -7
- data/spec/unit/actions/synchronize_user_filters_spec.rb +21 -0
- data/spec/unit/helpers/check_helper_production_spec.rb +34 -0
- data/spec/unit/helpers/check_helper_spec.rb +97 -9
- data/spec/unit/lcm/lcm2_spec.rb +67 -3
- data/spec/unit/models/blueprint/to_wire_spec.rb +1 -0
- data/spec/unit/models/dataset_blueprint.rb +14 -0
- data/spec/unit/models/from_wire_spec.rb +20 -0
- data/spec/unit/models/model_spec.rb +10 -0
- data/spec/unit/models/to_manifest_spec.rb +29 -0
- data/spec/unit/models/user_filters/user_filter_builder_spec.rb +44 -6
- data/spec/unit/rest/phmap_spec.rb +117 -0
- data/spec/vcr_configurer.rb +63 -0
- metadata +283 -24
- data/lib/gooddata/lcm/actions/ensure_segments.rb +0 -32
@@ -264,6 +264,9 @@ module GoodData
|
|
264
264
|
to_process = if process.path
|
265
265
|
to_process.delete if to_process
|
266
266
|
GoodData::Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project)
|
267
|
+
elsif process.component
|
268
|
+
to_process.delete if to_process
|
269
|
+
GoodData::Process.deploy_component(GoodData::Helpers.symbolize_keys(process.to_hash), project: to_project, client: to_project.client)
|
267
270
|
else
|
268
271
|
Dir.mktmpdir('etl_transfer') do |dir|
|
269
272
|
dir = Pathname(dir)
|
@@ -1172,22 +1175,15 @@ module GoodData
|
|
1172
1175
|
# @return [String] Returns token that you can use as input for object_import
|
1173
1176
|
def objects_export(objs, options = {})
|
1174
1177
|
fail 'Nothing to migrate. You have to pass list of objects, ids or uris that you would like to migrate' if objs.nil?
|
1175
|
-
objs = Array(objs)
|
1178
|
+
objs = Array(objs).map { |o| o.respond_to?(:uri) ? o.uri : o }
|
1176
1179
|
if objs.empty?
|
1177
1180
|
GoodData.logger.warn 'Nothing to migrate.'
|
1178
1181
|
return
|
1179
1182
|
end
|
1180
1183
|
|
1181
|
-
objs = objs.pmap { |obj| [obj, objects(obj)] }
|
1182
|
-
if objs.any? { |_, obj| obj.nil? }
|
1183
|
-
object = objs.select { |_, obj| obj.nil? }.map { |o, _| o }.join(', ')
|
1184
|
-
error_message = "Exporting objects failed with messages. " \
|
1185
|
-
"Object #{object} could not be found."
|
1186
|
-
fail ObjectsExportError, error_message
|
1187
|
-
end
|
1188
1184
|
export_payload = {
|
1189
1185
|
:partialMDExport => {
|
1190
|
-
:uris => objs
|
1186
|
+
:uris => objs,
|
1191
1187
|
:exportAttributeProperties => '1',
|
1192
1188
|
:crossDataCenterExport => '1'
|
1193
1189
|
}
|
@@ -1259,32 +1255,21 @@ module GoodData
|
|
1259
1255
|
if projects.is_a?(Array)
|
1260
1256
|
projects.each_slice(batch_size).flat_map do |batch|
|
1261
1257
|
batch.pmap do |proj|
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
}
|
1269
|
-
rescue RestClient::Exception => e
|
1270
|
-
{
|
1271
|
-
project: proj,
|
1272
|
-
exception: e,
|
1273
|
-
result: false,
|
1274
|
-
reason: GoodData::Helpers.interpolate_error_message(MultiJson.load(e.response))
|
1275
|
-
}
|
1276
|
-
rescue GoodData::ObjectsImportError => e
|
1277
|
-
{
|
1278
|
-
project: target_project,
|
1279
|
-
result: false,
|
1280
|
-
reason: e.message
|
1281
|
-
}
|
1282
|
-
end
|
1258
|
+
target_project = client.projects(proj)
|
1259
|
+
target_project.objects_import(token, options)
|
1260
|
+
{
|
1261
|
+
project: target_project,
|
1262
|
+
result: true
|
1263
|
+
}
|
1283
1264
|
end
|
1284
1265
|
end
|
1285
1266
|
else
|
1286
1267
|
target_project = client.projects(projects)
|
1287
1268
|
target_project.objects_import(token, options)
|
1269
|
+
[{
|
1270
|
+
project: target_project,
|
1271
|
+
result: true
|
1272
|
+
}]
|
1288
1273
|
end
|
1289
1274
|
end
|
1290
1275
|
|
@@ -1464,12 +1449,10 @@ module GoodData
|
|
1464
1449
|
#
|
1465
1450
|
# @return [Array<GoodData::ProjectRole>] List of roles
|
1466
1451
|
def roles
|
1467
|
-
url = "/gdc/projects/#{pid}/roles"
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
json = client.get role_url
|
1472
|
-
client.create(GoodData::ProjectRole, json, project: self)
|
1452
|
+
url = "/gdc/internal/projects/#{pid}/roles"
|
1453
|
+
res = client.get url
|
1454
|
+
res['internalProjectRoles']['roles'].map do |r|
|
1455
|
+
client.create(GoodData::ProjectRole, r, project: self)
|
1473
1456
|
end
|
1474
1457
|
end
|
1475
1458
|
|
@@ -42,7 +42,9 @@ module GoodData
|
|
42
42
|
_, project = GoodData.get_client_and_project(opts)
|
43
43
|
|
44
44
|
bp = ProjectBlueprint.new(spec)
|
45
|
-
|
45
|
+
maql_diff_params = [:includeGrain]
|
46
|
+
maql_diff_params << :excludeFactRule if opts[:exclude_fact_rule]
|
47
|
+
response = project.maql_diff(blueprint: bp, params: maql_diff_params)
|
46
48
|
|
47
49
|
GoodData.logger.debug("projectModelDiff") { response.pretty_inspect }
|
48
50
|
chunks = response['projectModelDiff']['updateScripts']
|
@@ -33,6 +33,7 @@ module GoodData
|
|
33
33
|
d[:updated] = data[:updated] || d[:created] || Time.now
|
34
34
|
d[:title] = data[:title]
|
35
35
|
d[:summary] = data[:summary]
|
36
|
+
d[:uri] = data[:uri]
|
36
37
|
end
|
37
38
|
new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
|
38
39
|
d['projectRole']['links']['self'] = data[:uri] if data[:uri]
|
@@ -54,7 +55,7 @@ module GoodData
|
|
54
55
|
#
|
55
56
|
# @return [Array<GoodData::Profile>] List of users
|
56
57
|
def users
|
57
|
-
url =
|
58
|
+
url = uri + '/users'
|
58
59
|
tmp = client.get url
|
59
60
|
tmp['associatedUsers']['users'].pmap do |user_url|
|
60
61
|
url = user_url
|
@@ -67,9 +68,7 @@ module GoodData
|
|
67
68
|
#
|
68
69
|
# @return [string] URI of this project role
|
69
70
|
def uri
|
70
|
-
|
71
|
-
return nil unless @json['projectRole']['links']['roleUsers']
|
72
|
-
@json['projectRole']['links']['roleUsers'].split('/')[0...-1].join('/')
|
71
|
+
@json['projectRole']['meta']['uri']
|
73
72
|
end
|
74
73
|
|
75
74
|
def ==(other)
|
@@ -77,7 +77,6 @@ module GoodData
|
|
77
77
|
else
|
78
78
|
fail 'Executable has to be provided' if executable.blank?
|
79
79
|
end
|
80
|
-
fail 'Trigger schedule has to be provided' if trigger.blank?
|
81
80
|
|
82
81
|
schedule = c.create(GoodData::Schedule, GoodData::Helpers.stringify_keys(GoodData::Helpers.deep_dup(SCHEDULE_TEMPLATE)), client: c, project: project)
|
83
82
|
|
@@ -403,7 +402,6 @@ module GoodData
|
|
403
402
|
#
|
404
403
|
# @return [Boolean] True if saved
|
405
404
|
def save
|
406
|
-
fail 'trigger schedule has to be provided' if cron.blank? && trigger_id.blank?
|
407
405
|
fail 'A timezone has to be provided' if timezone.blank?
|
408
406
|
fail 'Schedule type has to be provided' if schedule_type.blank?
|
409
407
|
rewrite_deprecated_params
|
@@ -28,7 +28,7 @@ module GoodData
|
|
28
28
|
result = c.get("/gdc/md/#{project.pid}/userfilters?count=#{count}&offset=#{offset}")
|
29
29
|
result['userFilters']['items'].each do |item|
|
30
30
|
item['userFilters'].each do |f|
|
31
|
-
user_lookup[f] = item['user']
|
31
|
+
user_lookup[f] = user_lookup[f] ? Array(user_lookup[f]).concat([item['user']]) : item['user']
|
32
32
|
end
|
33
33
|
end
|
34
34
|
break if result['userFilters']['length'] < offset
|
@@ -72,5 +72,13 @@ module GoodData
|
|
72
72
|
res = client.post(project.md['obj'], data)
|
73
73
|
@json[:uri] = res['uri']
|
74
74
|
end
|
75
|
+
|
76
|
+
def related
|
77
|
+
if related_uri.is_a? Array
|
78
|
+
related_uri.map { |u| super u }
|
79
|
+
else
|
80
|
+
super
|
81
|
+
end
|
82
|
+
end
|
75
83
|
end
|
76
84
|
end
|
@@ -30,8 +30,7 @@ module GoodData
|
|
30
30
|
# Returns the the object of this filter is related to. It can be either project or a user
|
31
31
|
#
|
32
32
|
# @return [GoodData::Project | GoodData::Profile] Related object
|
33
|
-
def related
|
34
|
-
uri = related_uri
|
33
|
+
def related(uri = related_uri)
|
35
34
|
return unless uri
|
36
35
|
level == :project ? client.projects(uri) : client.create(GoodData::Profile, client.get(uri))
|
37
36
|
end
|
@@ -5,6 +5,7 @@
|
|
5
5
|
# LICENSE file in the root directory of this source tree.
|
6
6
|
|
7
7
|
require_relative '../project_log_formatter'
|
8
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
8
9
|
|
9
10
|
module GoodData
|
10
11
|
module UserFilterBuilder
|
@@ -270,10 +271,10 @@ module GoodData
|
|
270
271
|
attrs_cache = create_attrs_cache(filters, options)
|
271
272
|
create_filter_proc = proc do |login, f|
|
272
273
|
expression, errors = create_expression(f, labels_cache, lookups_cache, attrs_cache, options)
|
274
|
+
safe_login = login.downcase
|
273
275
|
profiles_uri = if options[:type] == :muf
|
274
276
|
project_user = project_users.find { |u| u.login == login }
|
275
|
-
|
276
|
-
project_user.nil? ? ('/gdc/account/profile/' + login) : project_user.profile_url
|
277
|
+
project_user.nil? ? ('/gdc/account/profile/' + safe_login) : project_user.profile_url
|
277
278
|
elsif options[:type] == :variable
|
278
279
|
(users_cache[login] && users_cache[login].uri)
|
279
280
|
else
|
@@ -384,7 +385,14 @@ module GoodData
|
|
384
385
|
else
|
385
386
|
GoodData.logger.warn("Data permissions computed: #{to_create.count} to create and #{to_delete.count} to delete")
|
386
387
|
end
|
387
|
-
|
388
|
+
|
389
|
+
if dry_run
|
390
|
+
create_results = to_create.map { |x| { status: 'dry_run', user: x.first, type: 'create' } }
|
391
|
+
delete_results = to_delete.map { |x| { status: 'dry_run', user: x.first, type: 'delete' } }
|
392
|
+
return { created: {},
|
393
|
+
deleted: {},
|
394
|
+
results: create_results + delete_results }
|
395
|
+
end
|
388
396
|
|
389
397
|
create_results = to_create.each_slice(100).flat_map do |batch|
|
390
398
|
batch.pmapcat do |related_uri, group|
|
@@ -414,6 +422,8 @@ module GoodData
|
|
414
422
|
end
|
415
423
|
|
416
424
|
project_log_formatter.log_user_filter_results(create_results, to_create)
|
425
|
+
create_errors = create_results.select { |r| r[:status] == :failed }
|
426
|
+
fail "Creating MUFs resulted in errors: #{create_errors}" if create_errors.any?
|
417
427
|
|
418
428
|
delete_results = unless options[:do_not_touch_filters_that_are_not_mentioned]
|
419
429
|
to_delete.each_slice(100).flat_map do |batch|
|
@@ -444,6 +454,8 @@ module GoodData
|
|
444
454
|
end
|
445
455
|
|
446
456
|
project_log_formatter.log_user_filter_results(delete_results, to_delete)
|
457
|
+
delete_errors = delete_results.select { |r| r[:status] == :failed } if delete_results
|
458
|
+
fail "Deleting MUFs resulted in errors: #{delete_errors}" if delete_errors && delete_errors.any?
|
447
459
|
|
448
460
|
{ created: to_create, deleted: to_delete, results: create_results + (delete_results || []) }
|
449
461
|
end
|
@@ -541,13 +553,13 @@ module GoodData
|
|
541
553
|
# if this does not happen, users that are about to be deleted by users_brick
|
542
554
|
# would have all their filters removed now, which is not desirable
|
543
555
|
def self.sanitize_filters_to_delete(to_delete, users_brick_input, project_users)
|
544
|
-
return
|
556
|
+
return [] unless users_brick_input && users_brick_input.any?
|
545
557
|
user_profiles = users_brick_input.map do |user|
|
546
|
-
result = project_users.find { |u| u.login == user['login'] }
|
558
|
+
result = project_users.find { |u| u.login == user.with_indifferent_access['login'] }
|
547
559
|
next unless result
|
548
560
|
result.profile_url
|
549
561
|
end.compact
|
550
|
-
return
|
562
|
+
return [] unless user_profiles.any?
|
551
563
|
to_delete.reject do |_, value|
|
552
564
|
user_profiles.none? { |profile| profile == value.first.json[:related] }
|
553
565
|
end
|
data/lib/gooddata/rest/client.rb
CHANGED
@@ -17,48 +17,6 @@ require_relative '../helpers/global_helpers'
|
|
17
17
|
|
18
18
|
require_relative 'phmap'
|
19
19
|
|
20
|
-
module RestClient
|
21
|
-
module AbstractResponse
|
22
|
-
alias_method :old_follow_redirection, :follow_redirection
|
23
|
-
def follow_redirection(request = nil, result = nil, &block)
|
24
|
-
if RestClient::VERSION != '1.8.0'
|
25
|
-
fail 'Using monkey patched version of RestClient::AbstractResponse#' \
|
26
|
-
'follow_redirection which is guaranteed to be compatible only ' \
|
27
|
-
'with RestClient 1.8.0'
|
28
|
-
end
|
29
|
-
|
30
|
-
new_args = @args.dup
|
31
|
-
|
32
|
-
url = headers[:location]
|
33
|
-
url = URI.parse(request.url).merge(url).to_s if url !~ /^http/
|
34
|
-
|
35
|
-
new_args[:url] = url
|
36
|
-
if request
|
37
|
-
fail MaxRedirectsReached if request.max_redirects.zero?
|
38
|
-
new_args[:password] = request.password
|
39
|
-
new_args[:user] = request.user
|
40
|
-
new_args[:headers] = request.headers
|
41
|
-
new_args[:max_redirects] = request.max_redirects - 1
|
42
|
-
|
43
|
-
# TODO: figure out what to do with original :cookie, :cookies values
|
44
|
-
new_args[:cookies] = get_redirection_cookies(request, result, new_args)
|
45
|
-
end
|
46
|
-
|
47
|
-
Request.execute(new_args, &block)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Returns cookies which should be passed when following redirect
|
51
|
-
#
|
52
|
-
# @param request [RestClient::Request] Original request
|
53
|
-
# @param result [Net::HTTPResponse] Response
|
54
|
-
# @param args [Hash] Original arguments
|
55
|
-
# @return [Hash] Cookies to be passsed when following redirect
|
56
|
-
def get_redirection_cookies(request, _result, _args)
|
57
|
-
request.cookies
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
20
|
module GoodData
|
63
21
|
module Rest
|
64
22
|
class RestRetryError < StandardError
|
@@ -210,13 +168,23 @@ module GoodData
|
|
210
168
|
|
211
169
|
# Reset old cookies first
|
212
170
|
if options[:sst_token]
|
213
|
-
|
171
|
+
headers = {
|
172
|
+
:x_gdc_authsst => options[:sst_token],
|
173
|
+
:x_gdc_authtt => options[:tt_token]
|
174
|
+
}
|
175
|
+
merge_headers!(headers)
|
214
176
|
get('/gdc/account/token', @request_params)
|
215
177
|
|
216
178
|
@user = get(get('/gdc/app/account/bootstrap')['bootstrapResource']['accountSetting']['links']['self'])
|
217
179
|
GoodData.logger.info("Connected using SST to server #{@server.url} to profile \"#{@user['accountSetting']['login']}\"")
|
218
180
|
@auth = {}
|
219
181
|
refresh_token :dont_reauth => true
|
182
|
+
elsif options[:headers][:x_gdc_authsst]
|
183
|
+
@request_params = options[:headers]
|
184
|
+
@user = get('/gdc/app/account/bootstrap')['bootstrapResource']
|
185
|
+
GoodData.logger.info("Connected using SST to server #{@server.url} to profile \"#{@user['accountSetting']['login']}\"")
|
186
|
+
@auth = {}
|
187
|
+
refresh_token :dont_reauth => true
|
220
188
|
else
|
221
189
|
GoodData.logger.info("Connected using username \"#{username}\" to server #{@server.url}")
|
222
190
|
credentials = Connection.construct_login_payload(username, password)
|
@@ -656,9 +624,7 @@ ERR
|
|
656
624
|
placeholders = true
|
657
625
|
|
658
626
|
if placeholders
|
659
|
-
|
660
|
-
break if title.gsub!(pm[1], pm[0])
|
661
|
-
end
|
627
|
+
title = self.class.map_placeholders(title)
|
662
628
|
end
|
663
629
|
|
664
630
|
stat = stats[title]
|
data/lib/gooddata/rest/phmap.rb
CHANGED
@@ -7,74 +7,119 @@
|
|
7
7
|
module GoodData
|
8
8
|
module Rest
|
9
9
|
class Connection
|
10
|
+
def self.map_placeholders(title)
|
11
|
+
PH_MAP.each do |pm|
|
12
|
+
break if title.gsub!(pm[1], pm[0])
|
13
|
+
end
|
14
|
+
title
|
15
|
+
end
|
16
|
+
|
10
17
|
# PH_MAP for wildcarding of URLs in reports
|
11
18
|
PH_MAP = [
|
12
|
-
['/gdc/
|
13
|
-
|
14
|
-
['/gdc/
|
15
|
-
|
19
|
+
['/gdc/projects/{id}/execute', %r{/gdc/projects/[^\/]+/execute}],
|
20
|
+
|
21
|
+
['/gdc/dataload/projects/{id}/outputStage', %r{/gdc/dataload/projects/[^\/]+/outputStage}],
|
22
|
+
|
23
|
+
['/gdc/datawarehouse/instances/{id}', %r{/gdc/datawarehouse/instances/[^\/]+}],
|
24
|
+
['/gdc/datawarehouse/executions/{id}', %r{/gdc/datawarehouse/executions/[^\/]+}],
|
16
25
|
|
17
|
-
|
26
|
+
# domain dataproducts' clients
|
27
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/clients?segment={segment}',
|
28
|
+
%r{\/gdc\/domains\/[^\/]+\/dataproducts\/[^\/]+\/clients\?.*segment=[^\/]+}],
|
29
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/clients/{client}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/clients/[^\/]+}],
|
30
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/clients', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/clients}],
|
18
31
|
|
19
|
-
|
20
|
-
['/gdc/
|
32
|
+
# domain dataproducts' segments
|
33
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
|
34
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
|
35
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}/synchronizeClients/results/{result}',
|
36
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+}],
|
37
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/segments/{segment}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+}],
|
38
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/segments', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/segments}],
|
21
39
|
|
40
|
+
# domain dataproducts' provision & update
|
41
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects/results/{result}/details?offset={offset}&limit={limit}',
|
42
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
|
43
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects/results/{result}',
|
44
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects/results/[^\/]+}],
|
45
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/provisionClientProjects',
|
46
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/provisionClientProjects}],
|
47
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/updateClients?deleteExtraInSegments={segments}',
|
48
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/updateClients\?deleteExtraInSegments=[^\/]+}],
|
49
|
+
['/gdc/domains/{id}/dataproducts/{data_product}/updateClients',
|
50
|
+
%r{/gdc/domains/[^\/]+/dataproducts/[^\/]+/updateClients}],
|
51
|
+
|
52
|
+
# domain dataproduct
|
53
|
+
['/gdc/domains/{id}/dataproducts/{data_product}', %r{/gdc/domains/[^\/]+/dataproducts/[^\/]+}],
|
54
|
+
['/gdc/domains/{id}/dataproducts', %r{/gdc/domains/[^\/]+/dataproducts}],
|
55
|
+
|
56
|
+
# domain segments
|
22
57
|
['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
|
23
|
-
%r{/gdc/domains/[
|
58
|
+
%r{/gdc/domains/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
|
24
59
|
['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}',
|
25
|
-
%r{/gdc/domains/[
|
26
|
-
['/gdc/domains/{id}/segments/{segment}/', %r{/gdc/domains/[
|
27
|
-
['/gdc/domains/{id}/segments/{segment}', %r{/gdc/domains/[
|
28
|
-
|
29
|
-
|
30
|
-
['/gdc/domains/{id}/clients
|
31
|
-
['/gdc/domains/{id}/clients/{client_id}', %r{/gdc/domains/[
|
60
|
+
%r{/gdc/domains/[^\/]+/segments/[^\/]+/synchronizeClients/results/[^\/]+}],
|
61
|
+
['/gdc/domains/{id}/segments/{segment}/', %r{/gdc/domains/[^\/]+/segments/[^\/]+/}],
|
62
|
+
['/gdc/domains/{id}/segments/{segment}', %r{/gdc/domains/[^\/]+/segments/[^\/]+}],
|
63
|
+
|
64
|
+
# domain clients
|
65
|
+
['/gdc/domains/{id}/clients?segment={segment}', %r{/gdc/domains/[^\/]+/clients\?segment=[^\/]+}],
|
66
|
+
['/gdc/domains/{id}/clients/{client_id}/settings/lcm.title', %r{/gdc/domains/[^\/]+/clients/[^\/]+/settings/lcm.title}],
|
67
|
+
['/gdc/domains/{id}/clients/{client_id}/settings/lcm.token', %r{/gdc/domains/[^\/]+/clients/[^\/]+/settings/lcm.token}],
|
68
|
+
['/gdc/domains/{id}/clients/{client_id}', %r{/gdc/domains/[^\/]+/clients/[^\/]+}],
|
32
69
|
['/gdc/domains/{id}/provisionClientProjects/results/{result}/details?offset={offset}&limit={limit}',
|
33
|
-
%r{/gdc/domains/[
|
34
|
-
['/gdc/domains/{id}/provisionClientProjects/results/{result}', %r{/gdc/domains/[
|
35
|
-
['/gdc/domains/{id}/provisionClientProjects', %r{/gdc/domains/[
|
36
|
-
['/gdc/domains/{id}/updateClients', %r{/gdc/domains/[
|
37
|
-
['/gdc/domains/{id}/', %r{/gdc/domains/[
|
70
|
+
%r{/gdc/domains/[^\/]+/provisionClientProjects/results/[^\/]+/details\?offset=[\d]+&limit=[\d]+}],
|
71
|
+
['/gdc/domains/{id}/provisionClientProjects/results/{result}', %r{/gdc/domains/[^\/]+/provisionClientProjects/results/[^\/]+}],
|
72
|
+
['/gdc/domains/{id}/provisionClientProjects', %r{/gdc/domains/[^\/]+/provisionClientProjects}],
|
73
|
+
['/gdc/domains/{id}/updateClients', %r{/gdc/domains/[^\/]+/updateClients}],
|
74
|
+
['/gdc/domains/{id}/', %r{/gdc/domains/[^\/]+/}],
|
38
75
|
|
39
|
-
['/gdc/exporter/result/{id}/{id}', %r{/gdc/exporter/result/[
|
76
|
+
['/gdc/exporter/result/{id}/{id}', %r{/gdc/exporter/result/[^\/]+/[^\/]+}],
|
40
77
|
|
41
78
|
['/gdc/internal/lcm/domains/{id}/dataproducts/{data_product}/segments/{segment}/syncProcesses/{process}',
|
42
|
-
%r{/gdc/internal/lcm/domains/[
|
79
|
+
%r{/gdc/internal/lcm/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/syncProcesses/[^\/]+}],
|
43
80
|
['/gdc/internal/lcm/domains/{id}/dataproducts/{data_product}/segments/{segment}/syncProcesses',
|
44
|
-
%r{/gdc/internal/lcm/domains/[
|
45
|
-
|
46
|
-
['/gdc/internal/projects/{id}/objects/setPermissions', %r{/gdc/internal/projects/[
|
47
|
-
|
48
|
-
['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[
|
49
|
-
['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[
|
50
|
-
['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[
|
51
|
-
['/gdc/md/{id}/using2/{id}', %r{/gdc/md/[
|
52
|
-
['/gdc/md/{id}/userfilters?users={users}', %r{
|
53
|
-
['/gdc/md/{id}/userfilters?count={count}&offset={offset}', %r{/gdc/md/[
|
54
|
-
['/gdc/md/{id}/usedby2/{id}/{id}', %r{/gdc/md/[
|
55
|
-
['/gdc/md/{id}/usedby2/{id}', %r{/gdc/md/[
|
56
|
-
['/gdc/md/{id}/tasks/{id}/status', %r{/gdc/md/[
|
57
|
-
['/gdc/md/{id}/obj/{id}/validElements', %r{/gdc/md/[
|
58
|
-
['/gdc/md/{id}/obj/{id}/elements', %r{/gdc/md/[
|
59
|
-
['/gdc/md/{id}/obj/{id}', %r{/gdc/md/[
|
60
|
-
['/gdc/md/{id}/etltask/{id}', %r{/gdc/md/[
|
61
|
-
['/gdc/md/{id}/dataResult/{id}', %r{/gdc/md/[
|
62
|
-
['/gdc/md/{id}', %r{/gdc/md/[
|
63
|
-
|
64
|
-
['/gdc/projects/{id}/users/{id}/roles', %r{/gdc/projects/[
|
65
|
-
['/gdc/projects/{id}/users/{id}/permissions', %r{/gdc/projects/[
|
66
|
-
['/gdc/projects/{id}/users', %r{/gdc/projects/[
|
67
|
-
['/gdc/projects/{id}/schedules/{id}/executions/{id}', %r{/gdc/projects/[
|
68
|
-
['/gdc/projects/{id}/schedules/{id}', %r{/gdc/projects/[
|
69
|
-
['/gdc/projects/{id}/roles/{id}', %r{/gdc/projects/[
|
70
|
-
['/gdc/projects/{id}/model/view/{id}', %r{/gdc/projects/[
|
71
|
-
['/gdc/projects/{id}/model/view', %r{/gdc/projects/[
|
72
|
-
['/gdc/projects/{id}/model/diff/{id}', %r{/gdc/projects/[
|
73
|
-
['/gdc/projects/{id}/model/diff', %r{/gdc/projects/[
|
74
|
-
['/gdc/projects/{id}/dataload/
|
75
|
-
['/gdc/projects/{id}/dataload/processes/{id}', %r{/gdc/projects/[
|
76
|
-
['/gdc/projects/{id}/', %r{/gdc/projects/[
|
77
|
-
['/gdc/projects/{id}', %r{/gdc/projects/[
|
81
|
+
%r{/gdc/internal/lcm/domains/[^\/]+/dataproducts/[^\/]+/segments/[^\/]+/syncProcesses}],
|
82
|
+
|
83
|
+
['/gdc/internal/projects/{id}/objects/setPermissions', %r{/gdc/internal/projects/[^\/]+/objects/setPermissions}],
|
84
|
+
|
85
|
+
['/gdc/md/{id}/variables/item/{id}', %r{/gdc/md/[^\/]+/variables/item/[\d]+}],
|
86
|
+
['/gdc/md/{id}/validate/task/{id}', %r{/gdc/md/[^\/]+/validate/task/[^\/]+}],
|
87
|
+
['/gdc/md/{id}/using2/{id}/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+/[\d]+}],
|
88
|
+
['/gdc/md/{id}/using2/{id}', %r{/gdc/md/[^\/]+/using2/[\d]+}],
|
89
|
+
['/gdc/md/{id}/userfilters?users={users}', %r{\/gdc\/md\/[^\/]+\/userfilters\?users=[\/\w+@.]+}],
|
90
|
+
['/gdc/md/{id}/userfilters?count={count}&offset={offset}', %r{/gdc/md/[^\/]+/userfilters\?count=[\d]+&offset=[\d]+}],
|
91
|
+
['/gdc/md/{id}/usedby2/{id}/{id}', %r{/gdc/md/[^\/]+/usedby2/[\d]+/[\d]+}],
|
92
|
+
['/gdc/md/{id}/usedby2/{id}', %r{/gdc/md/[^\/]+/usedby2/[\d]+}],
|
93
|
+
['/gdc/md/{id}/tasks/{id}/status', %r{/gdc/md/[^\/]+/tasks/[^\/]+/status}],
|
94
|
+
['/gdc/md/{id}/obj/{id}/validElements', %r{/gdc/md/[^\/]+/obj/[\d]+/validElements(/)?(\?.*)?}],
|
95
|
+
['/gdc/md/{id}/obj/{id}/elements', %r{/gdc/md/[^\/]+/obj/[\d]+/elements(/)?(\?.*)?}],
|
96
|
+
['/gdc/md/{id}/obj/{id}', %r{/gdc/md/[^\/]+/obj/[\d]+}],
|
97
|
+
['/gdc/md/{id}/etltask/{id}', %r{/gdc/md/[^\/]+/etltask/[^\/]+}],
|
98
|
+
['/gdc/md/{id}/dataResult/{id}', %r{/gdc/md/[^\/]+/dataResult/[\d]+}],
|
99
|
+
['/gdc/md/{id}', %r{/gdc/md/[^\/]+}],
|
100
|
+
|
101
|
+
['/gdc/projects/{id}/users/{id}/roles', %r{/gdc/projects/[^\/]+/users/[^\/]+/roles}],
|
102
|
+
['/gdc/projects/{id}/users/{id}/permissions', %r{/gdc/projects/[^\/]+/users/[^\/]+/permissions}],
|
103
|
+
['/gdc/projects/{id}/users', %r{/gdc/projects/[^\/]+/users}],
|
104
|
+
['/gdc/projects/{id}/schedules/{id}/executions/{id}', %r{/gdc/projects/[^\/]+/schedules/[^\/]+/executions/[^\/]+}],
|
105
|
+
['/gdc/projects/{id}/schedules/{id}', %r{/gdc/projects/[^\/]+/schedules/[^\/]+}],
|
106
|
+
['/gdc/projects/{id}/roles/{id}', %r{/gdc/projects/[^\/]+/roles/[\d]+}],
|
107
|
+
['/gdc/projects/{id}/model/view/{id}', %r{/gdc/projects/[^\/]+/model/view/[^\/]+}],
|
108
|
+
['/gdc/projects/{id}/model/view', %r{/gdc/projects/[^\/]+/model/view}],
|
109
|
+
['/gdc/projects/{id}/model/diff/{id}', %r{/gdc/projects/[^\/]+/model/diff/[^\/]+}],
|
110
|
+
['/gdc/projects/{id}/model/diff', %r{/gdc/projects/[^\/]+/model/diff}],
|
111
|
+
['/gdc/projects/{id}/dataload/metadata/{project}', %r{/gdc/projects/[^\/]+/dataload/metadata/[^\/]+}],
|
112
|
+
['/gdc/projects/{id}/dataload/processes/{id}/executions/{id}', %r{/gdc/projects/[^\/]+/dataload/processes/[^\/]+/executions/[^\/]+}],
|
113
|
+
['/gdc/projects/{id}/dataload/processes/{id}', %r{/gdc/projects/[^\/]+/dataload/processes/[^\/]+}],
|
114
|
+
['/gdc/projects/{id}/', %r{/gdc/projects/[^\/]+/}],
|
115
|
+
['/gdc/projects/{id}', %r{/gdc/projects/[^\/]+}],
|
116
|
+
|
117
|
+
['/gdc/userGroups/{id}', %r{/gdc/userGroups/[^\/]+}],
|
118
|
+
|
119
|
+
['/gdc/account/profile/{id}', %r{/gdc/account/profile/[^\/]+}],
|
120
|
+
['/gdc/account/login/{id}', %r{/gdc/account/login/[^\/]+}],
|
121
|
+
['/gdc/account/domains/{id}/users?login={login}', %r{/gdc/account/domains/[^\/]+/users\?login=[^&$]+}],
|
122
|
+
['/gdc/account/domains/{id}', %r{/gdc/account/domains/[^\/]+}]
|
78
123
|
]
|
79
124
|
end
|
80
125
|
end
|