gooddata 0.6.28 → 0.6.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gooddata.rb +1 -0
- data/lib/gooddata/lcm/lcm.rb +83 -0
- data/lib/gooddata/mixins/is_folder.rb +11 -0
- data/lib/gooddata/models/metadata/folder.rb +46 -0
- data/lib/gooddata/models/process.rb +45 -2
- data/lib/gooddata/models/project.rb +18 -7
- data/lib/gooddata/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c9aacac281a0f84f0f83707d71e5ee748f5aef2
|
4
|
+
data.tar.gz: d3e7b086b137937b47476d5d1836961dbbdd522c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f1f7c1f95a122a5b002bc065e3690d8fea21ae5e99d83194c21de1a6b8df063977bb69215df5ddbf2ef787daf3c05c1ea7a9f3d39c75561e1e0c33b8c791ed0
|
7
|
+
data.tar.gz: cba38ea21ac0a82bf722da578210c9ff45f787c6e0195d3aebd16ff1cbb2748e17a94679d43ac805584f268d94c6f6b3a74cacaf3d92069e697fc7d284fdbb72
|
data/lib/gooddata.rb
CHANGED
@@ -18,6 +18,7 @@ require_relative 'gooddata/core/core'
|
|
18
18
|
require_relative 'gooddata/data/data'
|
19
19
|
require_relative 'gooddata/exceptions/exceptions'
|
20
20
|
require_relative 'gooddata/helpers/helpers'
|
21
|
+
require_relative 'gooddata/lcm/lcm'
|
21
22
|
require_relative 'gooddata/models/models'
|
22
23
|
|
23
24
|
# Files
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2016 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
module GoodData
|
8
|
+
module LCM
|
9
|
+
class << self
|
10
|
+
def ensure_users(domain, migration_spec, filter_on_segment = [])
|
11
|
+
messages = []
|
12
|
+
# Ensure technical user is in all projects
|
13
|
+
if migration_spec.key?(:technical_user)
|
14
|
+
clients = domain.clients
|
15
|
+
|
16
|
+
clients.peach do |c|
|
17
|
+
segment = c.segment
|
18
|
+
next if !filter_on_segment.empty? && !(filter_on_segment.include?(segment.id))
|
19
|
+
p = client.project
|
20
|
+
begin
|
21
|
+
p.create_users(migration_spec[:technical_user].map { |u| {login: u, role: 'admin'} })
|
22
|
+
rescue RestClient::Exception => e
|
23
|
+
messages << {type: :technical_user_addition, status: 'ERROR', message: e.message}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
messages
|
28
|
+
end
|
29
|
+
|
30
|
+
def transfer_everything(client, domain, migration_spec, filter_on_segment = [])
|
31
|
+
puts 'Ensuring Users - warning: works across whole domain not just provided segment(s)'
|
32
|
+
ensure_users(domain, migration_spec, filter_on_segment)
|
33
|
+
|
34
|
+
puts 'Migrating Blueprints'
|
35
|
+
|
36
|
+
domain.segments.peach do |segment|
|
37
|
+
next if !filter_on_segment.empty? && !(filter_on_segment.include?(segment.id))
|
38
|
+
bp = segment.master_project.blueprint
|
39
|
+
segment.clients.each do |c|
|
40
|
+
p = c.project
|
41
|
+
p.update_from_blueprint(bp)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
puts 'Migrating Processes and Schedules'
|
46
|
+
|
47
|
+
deployment_client = migration_spec.key?(:user_for_deployment) ? GoodData.connect(migration_spec[:user_for_deployment]) : client
|
48
|
+
domain.clients.peach do |c|
|
49
|
+
segment = c.segment
|
50
|
+
next if !filter_on_segment.empty? && !(filter_on_segment.include?(segment.id))
|
51
|
+
segment_master = segment.master_project
|
52
|
+
project = c.project
|
53
|
+
# set metadata
|
54
|
+
project.set_metadata('GOODOT_CUSTOM_PROJECT_ID', c.id)
|
55
|
+
# copy processes
|
56
|
+
|
57
|
+
deployment_client_segment_master = deployment_client.projects(segment_master.pid)
|
58
|
+
deployment_client_project = deployment_client.projects(project.pid)
|
59
|
+
GoodData::Project.transfer_processes(deployment_client_segment_master, deployment_client_project)
|
60
|
+
|
61
|
+
GoodData::Project.transfer_schedules(segment_master, project)
|
62
|
+
|
63
|
+
# Set up unique parameters
|
64
|
+
deployment_client_project.schedules.peach do |s|
|
65
|
+
s.update_params('GOODOT_CUSTOM_PROJECT_ID' => c.id)
|
66
|
+
s.update_params('CLIENT_ID' => c.id)
|
67
|
+
s.update_params('SEGMENT_ID' => segment.id)
|
68
|
+
s.update_params(migration_spec[:additional_params] || {})
|
69
|
+
s.update_hidden_params(migration_spec[:additional_hidden_params] || {})
|
70
|
+
s.save
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
puts 'Migrating Dashboards'
|
75
|
+
if filter_on_segment.empty?
|
76
|
+
domain.synchronize_clients
|
77
|
+
else
|
78
|
+
filter_on_segment.map { |s| domain.segments(s).synchronize_clients }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
6
|
+
|
7
|
+
require_relative '../metadata'
|
8
|
+
require_relative '../../core/rest'
|
9
|
+
require_relative '../../mixins/is_folder'
|
10
|
+
|
11
|
+
require_relative 'metadata'
|
12
|
+
|
13
|
+
module GoodData
|
14
|
+
class Folder < GoodData::MdObject
|
15
|
+
include Mixin::IsFolder
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Method intended to get all objects of that type in a specified project
|
19
|
+
#
|
20
|
+
# @param options [Hash] the options hash
|
21
|
+
# @option options [Boolean] :full if passed true the subclass can decide to pull in full objects. This is desirable from the usability POV but unfortunately has negative impact on performance so it is not the default
|
22
|
+
# @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
|
23
|
+
def all(options = {:client => GoodData.connection, :project => GoodData.project})
|
24
|
+
query('folder', Folder, options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def entries
|
29
|
+
(self.json['folder']['content']['entries'] || []).pmap do |entry|
|
30
|
+
res = case self.json['folder']['content']['type'].first
|
31
|
+
when 'fact'
|
32
|
+
GoodData::Fact[entry['link'], :client => self.client, :project => self.project]
|
33
|
+
when 'metric'
|
34
|
+
GoodData::Metric[entry['link'], :client => self.client, :project => self.project]
|
35
|
+
else
|
36
|
+
GoodData::MdObject[entry['link'], :client => self.client, :project => self.project]
|
37
|
+
end
|
38
|
+
res
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def type
|
43
|
+
self.json['folder']['content']['type'][0]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -92,10 +92,12 @@ module GoodData
|
|
92
92
|
# @option options [String] :process_id ID of a process to be redeployed (do not set if you want to create a new process)
|
93
93
|
# @option options [Boolean] :verbose (false) Switch on verbose mode for detailed logging
|
94
94
|
def deploy(path, options = { :client => GoodData.client, :project => GoodData.project })
|
95
|
-
client, project = GoodData.get_client_and_project(options)
|
96
|
-
|
97
95
|
return deploy_brick(path, options) if path.to_s.start_with?(APP_STORE_URL)
|
98
96
|
|
97
|
+
return deploy_from_appstore(path, options) if (path =~ /\${.*}:(.*)\/(.*):\//) == 0
|
98
|
+
|
99
|
+
client, project = GoodData.get_client_and_project(options)
|
100
|
+
|
99
101
|
path = Pathname(path) || fail('Path is not specified')
|
100
102
|
files_to_exclude = options[:files_to_exclude].nil? ? [] : options[:files_to_exclude].map { |pname| Pathname(pname) }
|
101
103
|
process_id = options[:process_id]
|
@@ -165,6 +167,43 @@ module GoodData
|
|
165
167
|
end
|
166
168
|
end
|
167
169
|
|
170
|
+
def deploy_from_appstore(path, options = {:client => GoodData.client, :project => GoodData.project})
|
171
|
+
client, project = GoodData.get_client_and_project(options)
|
172
|
+
|
173
|
+
deploy_name = options[:name]
|
174
|
+
fail ArgumentError, 'options[:name] can not be nil or empty!' if deploy_name.nil? || deploy_name.empty?
|
175
|
+
|
176
|
+
verbose = options[:verbose] || false
|
177
|
+
puts HighLine.color("Deploying #{path}", HighLine::BOLD) if verbose
|
178
|
+
|
179
|
+
process_id = options[:process_id]
|
180
|
+
|
181
|
+
data = {
|
182
|
+
process: {
|
183
|
+
name: deploy_name,
|
184
|
+
path: path,
|
185
|
+
type: 'RUBY'
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
res =
|
190
|
+
if process_id.nil?
|
191
|
+
client.post("/gdc/projects/#{project.pid}/dataload/processes", data)
|
192
|
+
|
193
|
+
else
|
194
|
+
client.put("/gdc/projects/#{project.pid}/dataload/processes/#{process_id}", data)
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
if res.keys.first == 'asyncTask'
|
199
|
+
res = JSON.parse(client.poll_on_code(res['asyncTask']['links']['poll'], options.merge(process: false)))
|
200
|
+
end
|
201
|
+
|
202
|
+
process = client.create(Process, res, project: project)
|
203
|
+
puts HighLine.color("Deploy DONE #{path}", HighLine::GREEN) if verbose
|
204
|
+
process
|
205
|
+
end
|
206
|
+
|
168
207
|
# ----------------------------- Private Stuff
|
169
208
|
|
170
209
|
private
|
@@ -281,6 +320,10 @@ module GoodData
|
|
281
320
|
process['executables']
|
282
321
|
end
|
283
322
|
|
323
|
+
def path
|
324
|
+
process['path']
|
325
|
+
end
|
326
|
+
|
284
327
|
def schedules
|
285
328
|
project.schedules.select { |schedule| schedule.process_id == obj_id }
|
286
329
|
end
|
@@ -213,14 +213,21 @@ module GoodData
|
|
213
213
|
|
214
214
|
def transfer_processes(from_project, to_project)
|
215
215
|
from_project.processes.each do |process|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
216
|
+
to_process = to_project.processes.find { |p| p.name == process.name }
|
217
|
+
|
218
|
+
if process.path
|
219
|
+
to_process.delete if to_process
|
220
|
+
GoodData::Process.deploy_from_appstore(process.path, name: process.name, client: to_project.client, project: to_project)
|
221
|
+
else
|
222
|
+
Dir.mktmpdir('etl_transfer') do |dir|
|
223
|
+
dir = Pathname(dir)
|
224
|
+
filename = dir + 'process.zip'
|
225
|
+
File.open(filename, 'w') do |f|
|
226
|
+
f << process.download
|
227
|
+
end
|
228
|
+
|
229
|
+
to_process ? to_process.deploy(filename, type: process.type, name: process.name) : to_project.deploy_process(filename, type: process.type, name: process.name)
|
221
230
|
end
|
222
|
-
to_process = to_project.processes.find { |p| p.name == process.name }
|
223
|
-
to_process ? to_process.deploy(filename, type: process.type, name: process.name) : to_project.deploy_process(filename, type: process.type, name: process.name)
|
224
231
|
end
|
225
232
|
end
|
226
233
|
res = (from_project.processes + to_project.processes).map { |p| [p, p.name, p.type] }
|
@@ -495,6 +502,10 @@ module GoodData
|
|
495
502
|
result['exportArtifact']['token']
|
496
503
|
end
|
497
504
|
|
505
|
+
def folders(id = :all)
|
506
|
+
GoodData::Folder[id, project: self, client: client]
|
507
|
+
end
|
508
|
+
|
498
509
|
def user_groups(id = :all, options = {})
|
499
510
|
GoodData::UserGroup[id, options.merge(project: self)]
|
500
511
|
end
|
data/lib/gooddata/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gooddata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Kolesnikov
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-07
|
14
|
+
date: 2016-09-07 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -710,6 +710,7 @@ files:
|
|
710
710
|
- lib/gooddata/helpers/global_helpers.rb
|
711
711
|
- lib/gooddata/helpers/global_helpers_params.rb
|
712
712
|
- lib/gooddata/helpers/helpers.rb
|
713
|
+
- lib/gooddata/lcm/lcm.rb
|
713
714
|
- lib/gooddata/mixins/author.rb
|
714
715
|
- lib/gooddata/mixins/content_getter.rb
|
715
716
|
- lib/gooddata/mixins/content_property_reader.rb
|
@@ -722,6 +723,7 @@ files:
|
|
722
723
|
- lib/gooddata/mixins/is_attribute.rb
|
723
724
|
- lib/gooddata/mixins/is_dimension.rb
|
724
725
|
- lib/gooddata/mixins/is_fact.rb
|
726
|
+
- lib/gooddata/mixins/is_folder.rb
|
725
727
|
- lib/gooddata/mixins/is_label.rb
|
726
728
|
- lib/gooddata/mixins/links.rb
|
727
729
|
- lib/gooddata/mixins/md_finders.rb
|
@@ -793,6 +795,7 @@ files:
|
|
793
795
|
- lib/gooddata/models/metadata/dataset.rb
|
794
796
|
- lib/gooddata/models/metadata/dimension.rb
|
795
797
|
- lib/gooddata/models/metadata/fact.rb
|
798
|
+
- lib/gooddata/models/metadata/folder.rb
|
796
799
|
- lib/gooddata/models/metadata/label.rb
|
797
800
|
- lib/gooddata/models/metadata/metadata.rb
|
798
801
|
- lib/gooddata/models/metadata/metric.rb
|
@@ -990,7 +993,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
990
993
|
version: '0'
|
991
994
|
requirements: []
|
992
995
|
rubyforge_project:
|
993
|
-
rubygems_version: 2.
|
996
|
+
rubygems_version: 2.5.1
|
994
997
|
signing_key:
|
995
998
|
specification_version: 4
|
996
999
|
summary: A convenient Ruby wrapper around the GoodData RESTful API
|