superset 0.2.7 → 0.3.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +7 -0
- data/Dockerfile +2 -2
- data/README.md +6 -3
- data/doc/duplicate_dashboards.md +45 -6
- data/lib/superset/base_put_request.rb +4 -4
- data/lib/superset/chart/bulk_delete.rb +1 -1
- data/lib/superset/chart/delete.rb +1 -1
- data/lib/superset/chart/get.rb +7 -11
- data/lib/superset/chart/put.rb +2 -2
- data/lib/superset/dashboard/bulk_delete.rb +1 -1
- data/lib/superset/dashboard/cascade_ownership/add_new_owner.rb +54 -0
- data/lib/superset/dashboard/datasets/list.rb +15 -15
- data/lib/superset/dashboard/delete.rb +1 -1
- data/lib/superset/dashboard/put.rb +7 -24
- data/lib/superset/dashboard/warm_up_cache.rb +1 -1
- data/lib/superset/dataset/bulk_delete.rb +1 -1
- data/lib/superset/dataset/delete.rb +1 -1
- data/lib/superset/dataset/put.rb +2 -2
- data/lib/superset/services/duplicate_dashboard.rb +64 -29
- data/lib/superset/tag/add_to_object.rb +5 -5
- data/lib/superset/version.rb +1 -1
- data/superset.gemspec +12 -13
- metadata +62 -65
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f9be8bc52c7852af239721ed6e260a12e068bb35042ae0d7a78507d39c498017
|
|
4
|
+
data.tar.gz: 3ddd9c26deca3cc72bd046d83435d22383f2986cee3bcfdebe9e4db0f0749ea3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1e1e71dace1acffd37407100c583f9bb61e29fcffafabdd13bcad834c49366b190a068fbe90b529c809e3c8d786afb9a370656ac47d96adfd740985dbbe9917
|
|
7
|
+
data.tar.gz: bee9ae33375f128d4d9abc11259d9f300ac281c188ec90c26088af85c8620e10350ba44a1f1645403b9994fcadc8760e79d94098e373a2a07666f6991dee418a
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.4.4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
## Change Log
|
|
2
2
|
|
|
3
|
+
## 0.3.0 - 2025-11-26
|
|
4
|
+
* Rename reserved object_id to target_id in https://github.com/rdytech/superset-client/pull/58
|
|
5
|
+
* Add dashboard cascade ownship in https://github.com/rdytech/superset-client/pull/59
|
|
6
|
+
* allow dup dashboard dataset suffix naming override in https://github.com/rdytech/superset-client/pull/61
|
|
7
|
+
* Bump ruby 3 bump gems by https://github.com/rdytech/superset-client/pull/60
|
|
8
|
+
|
|
9
|
+
|
|
3
10
|
## 0.2.7 - 2025-10-16
|
|
4
11
|
* add to_h method to list classes for Hash output
|
|
5
12
|
* add ids method to list classes for array of ids output
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
|
@@ -22,11 +22,14 @@ Build, bundle and open a ruby console
|
|
|
22
22
|
docker-compose build
|
|
23
23
|
docker-compose run --rm app bundle install
|
|
24
24
|
docker-compose run --rm app bin/console
|
|
25
|
+
|
|
26
|
+
# note .. windows users may need to call ruby the bin/console file
|
|
27
|
+
docker-compose run --rm app ruby bin/console
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
## Setup Locally ( no docker )
|
|
30
|
+
## Setup Locally ( no docker )
|
|
28
31
|
|
|
29
|
-
Requires Ruby >=
|
|
32
|
+
Requires Ruby >= 3
|
|
30
33
|
|
|
31
34
|
Bundle install and open a ruby console.
|
|
32
35
|
|
|
@@ -37,7 +40,7 @@ bin/console
|
|
|
37
40
|
|
|
38
41
|
## Including in a Ruby app
|
|
39
42
|
|
|
40
|
-
Add to your Gemfile `gem 'superset'`
|
|
43
|
+
Add to your Gemfile `gem 'superset'`
|
|
41
44
|
And then execute: `bundle install`
|
|
42
45
|
Or install it yourself as `gem install superset`
|
|
43
46
|
|
data/doc/duplicate_dashboards.md
CHANGED
|
@@ -36,7 +36,7 @@ then you could go ahead and run something like this.
|
|
|
36
36
|
```ruby
|
|
37
37
|
Superset::Services::DuplicateDashboard.new(
|
|
38
38
|
source_dashboard_id: 90,
|
|
39
|
-
target_schema: '
|
|
39
|
+
target_schema: 'client_1',
|
|
40
40
|
target_database_id: 2
|
|
41
41
|
).perform
|
|
42
42
|
|
|
@@ -47,12 +47,12 @@ Superset::Services::DuplicateDashboard.new(
|
|
|
47
47
|
# cat log/superset-client.log
|
|
48
48
|
# INFO -- : >>>>>>>>>>>>>>>>> Starting DuplicateDashboard Service <<<<<<<<<<<<<<<<<<<<<<
|
|
49
49
|
# INFO -- : Source Dashboard URL: https://your-superset-host/superset/dashboard/90/
|
|
50
|
-
# INFO -- : Duplicating dashboard 90 into Target Schema:
|
|
50
|
+
# INFO -- : Duplicating dashboard 90 into Target Schema: client_1 in database 2
|
|
51
51
|
# INFO -- : Copy Dashboard/Charts Completed - New Dashboard ID: 401
|
|
52
52
|
# INFO -- : Duplicating Source Dataset examples.video_game_sales with id 11
|
|
53
|
-
# INFO -- : Finished. Duplicate Dataset Name video_game_sales-example_two with id 542
|
|
54
|
-
# INFO -- : Validating Dataset ID: 542 schema update to
|
|
55
|
-
# INFO -- : Successfully updated dataset schema to
|
|
53
|
+
# INFO -- : Finished. Duplicate Dataset Name video_game_sales-example_two-client_1 with id 542
|
|
54
|
+
# INFO -- : Validating Dataset ID: 542 schema update to client_1 on Database: 2
|
|
55
|
+
# INFO -- : Successfully updated dataset schema to client_1 on Database: 2
|
|
56
56
|
# INFO -- : Updating Charts to point to New Datasets and updating Dashboard json_metadata ...
|
|
57
57
|
# INFO -- : Update Chart 55752 to new dataset_id 542
|
|
58
58
|
# INFO -- : Updated new Dashboard json_metadata charts with new dataset ids
|
|
@@ -71,14 +71,53 @@ If your using the embedded dashboards you can also provied attributes for
|
|
|
71
71
|
```ruby
|
|
72
72
|
Superset::Services::DuplicateDashboard.new(
|
|
73
73
|
source_dashboard_id: 37,
|
|
74
|
-
target_schema: '
|
|
74
|
+
target_schema: 'client_1',
|
|
75
75
|
target_database_id: 2,
|
|
76
76
|
allowed_domains: ["https://wylee-coyote-domain/"],
|
|
77
77
|
tags: ["product:acme_fu", "client:wylee_coyote", "embedded"],
|
|
78
78
|
publish: true
|
|
79
79
|
).perform
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Duplication when DB schemas are not used
|
|
86
|
+
|
|
87
|
+
If your multitenant setup is at the database level, and database structures are replicated into the same base schema, ie public,
|
|
88
|
+
then the target resulted datasets name must be overridden in order to get around the superset unique datasets name validation restriction. This can be done through the parameter 'target_dataset_suffix_override'.
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
Superset::Services::DuplicateDashboard.new(
|
|
92
|
+
source_dashboard_id: 90,
|
|
93
|
+
target_schema: 'public',
|
|
94
|
+
target_database_id: 2,
|
|
95
|
+
target_dataset_suffix_override: 'client_1'
|
|
96
|
+
).perform
|
|
97
|
+
|
|
80
98
|
```
|
|
81
99
|
|
|
100
|
+
## Duplication now supports catalogs
|
|
101
|
+
|
|
102
|
+
If you Database infrastructure uses catalogs, you can provide the target catalog as a paramater.
|
|
103
|
+
If there is only 1 catalog in the target database, then it will be used by default.
|
|
104
|
+
|
|
105
|
+
If multiple catalogs exist, and no catalog option is provided, an error will be raised.
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
Superset::Services::DuplicateDashboard.new(
|
|
109
|
+
source_dashboard_id: 90,
|
|
110
|
+
target_schema: 'public',
|
|
111
|
+
target_database_id: 2,
|
|
112
|
+
target_dataset_suffix_override: 'client_1',
|
|
113
|
+
target_catalog_name: 'staging_client_1',
|
|
114
|
+
).perform
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
82
121
|
### What is my Database ID ?
|
|
83
122
|
|
|
84
123
|
``` ruby
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Superset
|
|
2
2
|
class BasePutRequest < Superset::Request
|
|
3
|
-
attr_reader :
|
|
3
|
+
attr_reader :target_id, :params
|
|
4
4
|
|
|
5
|
-
def initialize(
|
|
6
|
-
@
|
|
5
|
+
def initialize(target_id: ,params: )
|
|
6
|
+
@target_id = target_id
|
|
7
7
|
@params = params
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -19,7 +19,7 @@ module Superset
|
|
|
19
19
|
private
|
|
20
20
|
|
|
21
21
|
def validate
|
|
22
|
-
raise "Error:
|
|
22
|
+
raise "Error: target_id integer is required" unless target_id.present? && target_id.is_a?(Integer)
|
|
23
23
|
raise "Error: params hash is required" unless params.present? && params.is_a?(Hash)
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -18,7 +18,7 @@ module Superset
|
|
|
18
18
|
raise InvalidParameterError, "chart_ids array of integers expected" unless chart_ids.is_a?(Array)
|
|
19
19
|
raise InvalidParameterError, "chart_ids array must contain Integer only values" unless chart_ids.all? { |item| item.is_a?(Integer) }
|
|
20
20
|
|
|
21
|
-
logger.info("
|
|
21
|
+
logger.info("Deleting charts with id: #{chart_ids.join(', ')}")
|
|
22
22
|
response
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -12,7 +12,7 @@ module Superset
|
|
|
12
12
|
def perform
|
|
13
13
|
raise InvalidParameterError, "chart_id integer is required" unless chart_id.present? && chart_id.is_a?(Integer)
|
|
14
14
|
|
|
15
|
-
logger.info("
|
|
15
|
+
logger.info("Deleting chart with id: #{chart_id}")
|
|
16
16
|
response
|
|
17
17
|
end
|
|
18
18
|
|
data/lib/superset/chart/get.rb
CHANGED
|
@@ -17,28 +17,24 @@ module Superset
|
|
|
17
17
|
self
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def result
|
|
21
|
-
[ super ]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
20
|
def datasource_id
|
|
25
|
-
if result
|
|
26
|
-
JSON.parse(result
|
|
27
|
-
elsif result
|
|
28
|
-
JSON.parse(result
|
|
21
|
+
if result['query_context'].present? && JSON.parse(result['query_context'])['datasource'].present?
|
|
22
|
+
JSON.parse(result['query_context'])['datasource']['id']
|
|
23
|
+
elsif result['params'].present? && JSON.parse(result['params'])['datasource'].present?
|
|
24
|
+
JSON.parse(result['params'])['datasource'].match(/^\d+/)[0].to_i
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
|
|
32
28
|
def owner_ids
|
|
33
|
-
result
|
|
29
|
+
result['owners'].map{|o| o['id']}
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
def params
|
|
37
|
-
JSON.parse(result
|
|
33
|
+
JSON.parse(result['params']) if result['params'].present?
|
|
38
34
|
end
|
|
39
35
|
|
|
40
36
|
def query_context
|
|
41
|
-
JSON.parse(result
|
|
37
|
+
JSON.parse(result['query_context']) if result['query_context'].present?
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
private
|
data/lib/superset/chart/put.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Usage:
|
|
4
4
|
# params = { owners: [ 58, 3 ] }
|
|
5
|
-
# Superset::Chart::Put.new(
|
|
5
|
+
# Superset::Chart::Put.new(target_id: 202, params: params ).perform
|
|
6
6
|
|
|
7
7
|
module Superset
|
|
8
8
|
module Chart
|
|
@@ -11,7 +11,7 @@ module Superset
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
13
|
def route
|
|
14
|
-
"chart/#{
|
|
14
|
+
"chart/#{target_id}"
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -20,7 +20,7 @@ module Superset
|
|
|
20
20
|
raise InvalidParameterError, "dashboard_ids array of integers expected" unless dashboard_ids.is_a?(Array)
|
|
21
21
|
raise InvalidParameterError, "dashboard_ids array must contain Integer only values" unless dashboard_ids.all? { |item| item.is_a?(Integer) }
|
|
22
22
|
|
|
23
|
-
logger.info("
|
|
23
|
+
logger.info("Deleting dashboards with id: #{dashboard_ids.join(', ')}")
|
|
24
24
|
response
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Superset
|
|
2
|
+
module Dashboard
|
|
3
|
+
module CascadeOwnership
|
|
4
|
+
class AddNewOwner < Superset::Request
|
|
5
|
+
attr_reader :dashboard_id, :user_id
|
|
6
|
+
|
|
7
|
+
def initialize(dashboard_id:, user_id:)
|
|
8
|
+
@dashboard_id = dashboard_id
|
|
9
|
+
@user_id = user_id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def perform
|
|
13
|
+
raise "Error: dashboard_id integer is required" unless dashboard_id.present? && dashboard_id.is_a?(Integer)
|
|
14
|
+
raise "Error: user_id integer is required" unless user_id.present? && user_id.is_a?(Integer)
|
|
15
|
+
|
|
16
|
+
add_user_to_dashboard_ownership
|
|
17
|
+
add_user_to_charts_ownership
|
|
18
|
+
add_user_to_datasets_ownership
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def add_user_to_dashboard_ownership
|
|
24
|
+
return if current_dashboard_owner_ids.include?(user_id)
|
|
25
|
+
Superset::Dashboard::Put.new(target_id: dashboard_id, params: { "owners": current_dashboard_owner_ids << user_id }).perform
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def add_user_to_charts_ownership
|
|
29
|
+
chart_ids = Superset::Dashboard::Charts::List.new(dashboard_id).ids
|
|
30
|
+
chart_ids.each do |chart_id|
|
|
31
|
+
current_chart_owner_ids = Superset::Chart::Get.new(chart_id).result['owners'].map{|c| c['id']}
|
|
32
|
+
next if current_chart_owner_ids.include?(user_id)
|
|
33
|
+
|
|
34
|
+
Superset::Chart::Put.new(target_id: chart_id, params: { "owners": current_chart_owner_ids << user_id }).perform
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_user_to_datasets_ownership
|
|
39
|
+
dataset_ids = Superset::Dashboard::Datasets::List.new(dashboard_id: dashboard_id).ids
|
|
40
|
+
dataset_ids.each do |dataset_id|
|
|
41
|
+
current_dataset_owner_ids = Superset::Dataset::Get.new(dataset_id).result['owners'].map{|c| c['id']}
|
|
42
|
+
next if current_dataset_owner_ids.include?(user_id)
|
|
43
|
+
|
|
44
|
+
Superset::Dataset::Put.new(target_id: dataset_id, params: { "owners": current_dataset_owner_ids << user_id }).perform
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def current_dashboard_owner_ids
|
|
49
|
+
@current_dashboard_owner_ids ||= Superset::Dashboard::Get.new(dashboard_id).result['owners'].map{|i| i['id'] }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -30,7 +30,7 @@ module Superset
|
|
|
30
30
|
# For the current superset setup we will assume a dashboard datasets will point to EXACTLY one schema, their own.
|
|
31
31
|
# if not .. we need to know about it. Potentially we could override this check if others do not consider it a problem.
|
|
32
32
|
if all_dashboard_schemas.count > 1
|
|
33
|
-
Rollbar.error("SUPERSET DASHBOARD ERROR: Dashboard id #{id} has multiple dataset schema linked: #{all_dashboard_schemas.to_s}")
|
|
33
|
+
Rollbar.error("SUPERSET DASHBOARD ERROR: Dashboard id #{id} has multiple dataset schema linked: #{all_dashboard_schemas.to_s}") if defined?(Rollbar)
|
|
34
34
|
end
|
|
35
35
|
all_dashboard_schemas
|
|
36
36
|
end
|
|
@@ -48,6 +48,20 @@ module Superset
|
|
|
48
48
|
chart_datasets + filter_datasets(filter_dataset_ids_not_used_in_charts)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def rows
|
|
52
|
+
datasets_details.map do |d|
|
|
53
|
+
[
|
|
54
|
+
d[:id],
|
|
55
|
+
d[:datasource_name],
|
|
56
|
+
d[:database][:id],
|
|
57
|
+
d[:database][:name],
|
|
58
|
+
d[:database][:backend],
|
|
59
|
+
d[:schema],
|
|
60
|
+
d[:filter_only]
|
|
61
|
+
]
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
51
65
|
private
|
|
52
66
|
|
|
53
67
|
def filter_dataset_ids
|
|
@@ -74,20 +88,6 @@ module Superset
|
|
|
74
88
|
['id', 'datasource_name', 'database_id', 'database_name', 'database_backend', 'schema', 'filter_only'].map(&:to_sym)
|
|
75
89
|
end
|
|
76
90
|
|
|
77
|
-
def rows
|
|
78
|
-
datasets_details.map do |d|
|
|
79
|
-
[
|
|
80
|
-
d[:id],
|
|
81
|
-
d[:datasource_name],
|
|
82
|
-
d[:database][:id],
|
|
83
|
-
d[:database][:name],
|
|
84
|
-
d[:database][:backend],
|
|
85
|
-
d[:schema],
|
|
86
|
-
d[:filter_only]
|
|
87
|
-
]
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
91
|
# when displaying a list of datasets, show dashboard title as well
|
|
92
92
|
def title
|
|
93
93
|
@title ||= [id, dashboard.title].join(' ')
|
|
@@ -1,36 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
# Example Usage: Update Dashboard Ownership to a new set of users
|
|
5
|
+
# this will override the existing owners and set the new owners
|
|
6
|
+
# params = { owners: [ 58, 3 ] }
|
|
7
|
+
# Superset::Dashboard::Put.new(target_id: 101, params: params ).perform
|
|
8
|
+
|
|
4
9
|
module Superset
|
|
5
10
|
module Dashboard
|
|
6
|
-
class Put < Superset::
|
|
7
|
-
|
|
8
|
-
attr_reader :target_dashboard_id, :params
|
|
9
|
-
|
|
10
|
-
def initialize(target_dashboard_id:, params:)
|
|
11
|
-
@target_dashboard_id = target_dashboard_id
|
|
12
|
-
@params = params
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def perform
|
|
16
|
-
raise "Error: target_dashboard_id integer is required" unless target_dashboard_id.present? && target_dashboard_id.is_a?(Integer)
|
|
17
|
-
raise "Error: params hash is required" unless params.present? && params.is_a?(Hash)
|
|
18
|
-
|
|
19
|
-
response
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def response
|
|
23
|
-
@response ||= client.put(route, params)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def id
|
|
27
|
-
response["result"]["id"]
|
|
28
|
-
end
|
|
11
|
+
class Put < Superset::BasePutRequest
|
|
29
12
|
|
|
30
13
|
private
|
|
31
14
|
|
|
32
15
|
def route
|
|
33
|
-
"dashboard/#{
|
|
16
|
+
"dashboard/#{target_id}"
|
|
34
17
|
end
|
|
35
18
|
end
|
|
36
19
|
end
|
|
@@ -19,7 +19,7 @@ module Superset
|
|
|
19
19
|
begin
|
|
20
20
|
warm_up_dataset(dataset["datasource_name"], dataset["name"])
|
|
21
21
|
rescue => e
|
|
22
|
-
Rollbar.error("Warm up cache failed for the dashboard #{dashboard_id.to_s} and for the dataset #{dataset["datasource_name"]} - #{e}")
|
|
22
|
+
Rollbar.error("Warm up cache failed for the dashboard #{dashboard_id.to_s} and for the dataset #{dataset["datasource_name"]} - #{e}") if defined?(Rollbar)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -19,7 +19,7 @@ module Superset
|
|
|
19
19
|
raise InvalidParameterError, "dataset_ids array of integers expected" unless dataset_ids.is_a?(Array)
|
|
20
20
|
raise InvalidParameterError, "dataset_ids array must contain Integer only values" unless dataset_ids.all? { |item| item.is_a?(Integer) }
|
|
21
21
|
|
|
22
|
-
logger.info("
|
|
22
|
+
logger.info("Deleting datasets with id: #{dataset_ids.join(', ')}")
|
|
23
23
|
response
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -12,7 +12,7 @@ module Superset
|
|
|
12
12
|
def perform
|
|
13
13
|
raise InvalidParameterError, "dataset_id integer is required" unless dataset_id.present? && dataset_id.is_a?(Integer)
|
|
14
14
|
|
|
15
|
-
logger.info("
|
|
15
|
+
logger.info("Deleting dataset with id: #{dataset_id}")
|
|
16
16
|
response
|
|
17
17
|
end
|
|
18
18
|
|
data/lib/superset/dataset/put.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Usage:
|
|
4
4
|
# params = { owners: [ 58, 3 ] }
|
|
5
|
-
# Superset::Dataset::Put.new(
|
|
5
|
+
# Superset::Dataset::Put.new(target_id: 101, params: params ).perform
|
|
6
6
|
|
|
7
7
|
module Superset
|
|
8
8
|
module Dataset
|
|
@@ -11,7 +11,7 @@ module Superset
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
13
|
def route
|
|
14
|
-
"dataset/#{
|
|
14
|
+
"dataset/#{target_id}"
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -9,15 +9,17 @@ module Superset
|
|
|
9
9
|
module Services
|
|
10
10
|
class DuplicateDashboard < Superset::Request
|
|
11
11
|
|
|
12
|
-
attr_reader :source_dashboard_id, :target_schema, :target_database_id, :allowed_domains, :tags, :publish
|
|
12
|
+
attr_reader :source_dashboard_id, :target_schema, :target_database_id, :target_dataset_suffix_override, :allowed_domains, :tags, :publish, :target_catalog_name
|
|
13
13
|
|
|
14
|
-
def initialize(source_dashboard_id:, target_schema:, target_database_id: , allowed_domains: [], tags: [], publish: false)
|
|
14
|
+
def initialize(source_dashboard_id:, target_schema:, target_database_id: , target_dataset_suffix_override: nil, allowed_domains: [], tags: [], publish: false, target_catalog_name: nil)
|
|
15
15
|
@source_dashboard_id = source_dashboard_id
|
|
16
16
|
@target_schema = target_schema
|
|
17
17
|
@target_database_id = target_database_id
|
|
18
|
+
@target_dataset_suffix_override = target_dataset_suffix_override
|
|
18
19
|
@allowed_domains = allowed_domains
|
|
19
20
|
@tags = tags
|
|
20
21
|
@publish = publish
|
|
22
|
+
@target_catalog_name = target_catalog_name
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def perform
|
|
@@ -55,6 +57,11 @@ module Superset
|
|
|
55
57
|
|
|
56
58
|
rescue => e
|
|
57
59
|
logger.error("#{e.message}")
|
|
60
|
+
remove_duplicated_objects
|
|
61
|
+
puts "------------------------------------------------------------------------------\n"
|
|
62
|
+
puts "DUPLICATE DASHBOARD FAILED - ERROR: #{e.message}\n"
|
|
63
|
+
puts "REMOVED DUPLICATED OBJECTS - Check log/superset-client.log for more details\n"
|
|
64
|
+
puts "------------------------------------------------------------------------------\n"
|
|
58
65
|
raise e
|
|
59
66
|
end
|
|
60
67
|
|
|
@@ -67,12 +74,12 @@ module Superset
|
|
|
67
74
|
def add_tags_to_new_dashboard
|
|
68
75
|
return unless tags.present?
|
|
69
76
|
|
|
70
|
-
Superset::Tag::AddToObject.new(object_type_id: ObjectType::DASHBOARD,
|
|
77
|
+
Superset::Tag::AddToObject.new(object_type_id: ObjectType::DASHBOARD, target_id: new_dashboard.id, tags: tags).perform
|
|
71
78
|
logger.info " Added tags to dashboard #{new_dashboard.id}: #{tags}"
|
|
72
79
|
rescue => e
|
|
73
80
|
# catching tag error and display in log .. but also alowing the process to finish logs as tag error is fairly insignificant
|
|
74
|
-
logger.error(" FAILED to add tags to new dashboard id: #{new_dashboard.id}. Error
|
|
75
|
-
|
|
81
|
+
logger.error(" FAILED to add tags to new dashboard id: #{new_dashboard.id}. Error: #{e.message}")
|
|
82
|
+
raise ValidationError, "Failed to add tags to new dashboard id: #{new_dashboard.id}. #{e.message}. Missing Tags Values are #{tags}"
|
|
76
83
|
end
|
|
77
84
|
|
|
78
85
|
def created_embedded_config
|
|
@@ -90,35 +97,39 @@ module Superset
|
|
|
90
97
|
|
|
91
98
|
def duplicate_source_dashboard_datasets
|
|
92
99
|
source_dashboard_datasets.each do |dataset|
|
|
93
|
-
# duplicate the dataset, renaming to use of suffix as the target_schema
|
|
94
|
-
# reason: there is a bug(or feature) in the SS
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
existing_datasets = Superset::Dataset::List.new(title_equals: new_dataset_name, schema_equals: target_schema).result
|
|
100
|
+
# duplicate the dataset, renaming to use of suffix as the target_schema OR target_dataset_suffix_override value
|
|
101
|
+
# reason: there is a bug(or feature) in the SS where a dataset name must be uniq when duplicating
|
|
102
|
+
target_dataset_name = new_dataset_name(dataset[:datasource_name])
|
|
103
|
+
existing_datasets = Superset::Dataset::List.new(title_equals: target_dataset_name, schema_equals: target_schema).result
|
|
98
104
|
if existing_datasets.any?
|
|
99
|
-
logger.info "Dataset #{
|
|
100
|
-
new_dataset_id = existing_datasets[0]["id"]
|
|
105
|
+
logger.info " Dataset #{target_dataset_name} already exists. Reusing it"
|
|
106
|
+
new_dataset_id = existing_datasets[0]["id"]
|
|
101
107
|
else
|
|
102
|
-
new_dataset_id = Superset::Dataset::Duplicate.new(source_dataset_id: dataset[:id], new_dataset_name:
|
|
108
|
+
new_dataset_id = Superset::Dataset::Duplicate.new(source_dataset_id: dataset[:id], new_dataset_name: target_dataset_name).perform
|
|
103
109
|
# update the new dataset with the target schema, database, catalog
|
|
104
110
|
Superset::Dataset::UpdateSchema.new(
|
|
105
111
|
source_dataset_id: new_dataset_id,
|
|
106
112
|
target_database_id: target_database_id,
|
|
107
113
|
target_schema: target_schema,
|
|
108
|
-
target_catalog:
|
|
114
|
+
target_catalog: validated_target_database_catalog_name).perform
|
|
109
115
|
end
|
|
110
116
|
# keep track of the previous dataset and the matching new dataset_id
|
|
111
117
|
dataset_duplication_tracker << { source_dataset_id: dataset[:id], new_dataset_id: new_dataset_id }
|
|
112
118
|
end
|
|
113
119
|
end
|
|
114
120
|
|
|
121
|
+
# if a suffix is provided, use it to suffix the dataset name
|
|
122
|
+
# if no suffix is provided, use the schema name as the suffix
|
|
123
|
+
def new_dataset_name(dataset_name)
|
|
124
|
+
return "#{dataset_name}-#{target_schema}" if target_dataset_suffix_override.blank?
|
|
125
|
+
"#{dataset_name}-#{target_dataset_suffix_override.downcase}"
|
|
126
|
+
end
|
|
127
|
+
|
|
115
128
|
def update_charts_with_new_datasets
|
|
116
129
|
logger.info "Updating Charts to point to New Datasets and updating Dashboard json_metadata ..."
|
|
117
130
|
# note dashboard json_metadata currently still points to the old chart ids and is updated here
|
|
118
|
-
|
|
119
131
|
new_dashboard_json_metadata_json_string = new_dashboard_json_metadata_configuration.to_json # need to convert to string for gsub
|
|
120
|
-
|
|
121
|
-
new_charts_list = Superset::Dashboard::Charts::List.new(new_dashboard.id).result
|
|
132
|
+
|
|
122
133
|
new_chart_ids_list = new_charts_list&.map { |r| r['id'] }&.compact
|
|
123
134
|
# get all chart details for the source dashboard
|
|
124
135
|
original_charts = Superset::Dashboard::Charts::List.new(source_dashboard_id).result.map { |r| [r['slice_name'], r['id']] }.to_h
|
|
@@ -148,6 +159,11 @@ module Superset
|
|
|
148
159
|
@new_dashboard_json_metadata_configuration = JSON.parse(new_dashboard_json_metadata_json_string)
|
|
149
160
|
end
|
|
150
161
|
|
|
162
|
+
def new_charts_list
|
|
163
|
+
# get all chart ids for the new dashboard
|
|
164
|
+
@new_charts_list ||= Superset::Dashboard::Charts::List.new(new_dashboard.id).result
|
|
165
|
+
end
|
|
166
|
+
|
|
151
167
|
def duplicate_source_dashboard_filters
|
|
152
168
|
return unless source_dashboard_filter_dataset_ids.length.positive?
|
|
153
169
|
|
|
@@ -164,11 +180,11 @@ module Superset
|
|
|
164
180
|
|
|
165
181
|
def update_source_dashboard_json_metadata
|
|
166
182
|
logger.info " Updated new Dashboard json_metadata charts with new dataset ids"
|
|
167
|
-
Superset::Dashboard::Put.new(
|
|
183
|
+
Superset::Dashboard::Put.new(target_id: new_dashboard.id, params: { "json_metadata" => @new_dashboard_json_metadata_configuration.to_json }).perform
|
|
168
184
|
end
|
|
169
185
|
|
|
170
186
|
def publish_dashboard
|
|
171
|
-
Superset::Dashboard::Put.new(
|
|
187
|
+
Superset::Dashboard::Put.new(target_id: new_dashboard.id, params: { published: publish } ).perform
|
|
172
188
|
end
|
|
173
189
|
|
|
174
190
|
def new_dashboard
|
|
@@ -209,7 +225,7 @@ module Superset
|
|
|
209
225
|
raise ValidationError, "One or more source dashboard filters point to a different schema than the dashboard charts. Identified Unpermittied Filter Dataset Ids are #{unpermitted_filter_dataset_ids.to_s}" if unpermitted_filter_dataset_ids.any?
|
|
210
226
|
|
|
211
227
|
# new dataset validations - Need to be commented for EU dashboard duplication as we are using the existing datasets for the new dashboard
|
|
212
|
-
raise ValidationError, "DATASET NAME CONFLICT: The Target Schema #{target_schema} already has existing datasets named: #{target_schema_matching_dataset_names.join(',')}" unless target_schema_matching_dataset_names.empty?
|
|
228
|
+
raise ValidationError, "DATASET NAME CONFLICT: The Target Database #{target_database_id} with Schema #{target_schema} already has existing datasets named: #{target_schema_matching_dataset_names.join(',')}" unless target_schema_matching_dataset_names.empty?
|
|
213
229
|
validate_source_dashboard_datasets_sql_does_not_hard_code_schema
|
|
214
230
|
|
|
215
231
|
# embedded allowed_domain validations
|
|
@@ -218,8 +234,8 @@ module Superset
|
|
|
218
234
|
|
|
219
235
|
def validate_source_dashboard_datasets_sql_does_not_hard_code_schema
|
|
220
236
|
errors = source_dashboard_datasets.map do |dataset|
|
|
221
|
-
"The Dataset ID #{dataset[:id]} SQL query is hard coded with the schema value
|
|
222
|
-
"Remove all direct embedded schema calls from the Dataset SQL query before continuing." if dataset[:sql]
|
|
237
|
+
"The Dataset ID #{dataset[:id]} SQL query is hard coded with the schema value: #{dataset[:schema]}. This indicates that the dataset can not be duplicated cleanly to point to the target schema. " +
|
|
238
|
+
"Remove all direct embedded schema calls from the Dataset SQL query before continuing." if dataset[:sql]&.include?("#{dataset[:schema]}.")
|
|
223
239
|
end.compact
|
|
224
240
|
raise ValidationError, errors.join("\n") unless errors.empty?
|
|
225
241
|
end
|
|
@@ -245,13 +261,15 @@ module Superset
|
|
|
245
261
|
source_dashboard_datasets.map { |dataset| dataset[:datasource_name] }.uniq
|
|
246
262
|
end
|
|
247
263
|
|
|
248
|
-
# identify any already existing datasets in the target schema that have the same name as the source dashboard datasets
|
|
264
|
+
# identify any already existing datasets in the target database and schema that have the same name as the source dashboard datasets + suffix
|
|
249
265
|
# note this is prior to adding the (COPY) suffix
|
|
250
|
-
# here we will need to decide if we want to use the existing dataset or not
|
|
266
|
+
# here we will need to decide if we want to use the existing dataset or not
|
|
251
267
|
# for now we will exit with an error if we find any existing datasets of the same name
|
|
252
268
|
def target_schema_matching_dataset_names
|
|
253
269
|
@target_schema_matching_dataset_names ||= source_dashboard_dataset_names.map do |source_dataset_name|
|
|
254
|
-
|
|
270
|
+
source_dataset_name_with_suffix = new_dataset_name(source_dataset_name)
|
|
271
|
+
|
|
272
|
+
existing_names = Superset::Dataset::List.new(title_contains: source_dataset_name_with_suffix, database_id_eq: target_database_id, schema_equals: target_schema).result.map{|t|t['table_name']}.uniq # contains match to cover with suffix as well
|
|
255
273
|
unless existing_names.flatten.empty?
|
|
256
274
|
logger.error " HALTING PROCESS: Schema #{target_schema} already has Dataset called #{existing_names}"
|
|
257
275
|
end
|
|
@@ -267,11 +285,13 @@ module Superset
|
|
|
267
285
|
@filter_dataset_ids ||= source_dashboard.filter_configuration.map { |c| c['targets'] }.flatten.compact.map { |c| c['datasetId'] }.flatten.compact.uniq
|
|
268
286
|
end
|
|
269
287
|
|
|
270
|
-
#
|
|
271
|
-
def
|
|
288
|
+
# if multiple catalogs are present, the target_catalog_name must be provided, otherwise use the first catalog
|
|
289
|
+
def validated_target_database_catalog_name
|
|
272
290
|
catalogs = Superset::Database::GetCatalogs.new(target_database_id).catalogs
|
|
273
|
-
|
|
274
|
-
|
|
291
|
+
return target_catalog_name if catalogs.include?(target_catalog_name)
|
|
292
|
+
|
|
293
|
+
raise ValidationError, "Target Database #{target_database_id} has multiple catalogs, must provide target_catalog_name" if catalogs.size > 1 && target_catalog_name.blank?
|
|
294
|
+
@validated_target_database_catalog_name ||= catalogs.find { |c| c['name'] == target_catalog_name } || catalogs.first
|
|
275
295
|
end
|
|
276
296
|
|
|
277
297
|
# Primary Assumption is that all charts datasets on the source dashboard are pointing to the same database schema
|
|
@@ -290,6 +310,21 @@ module Superset
|
|
|
290
310
|
end
|
|
291
311
|
end
|
|
292
312
|
|
|
313
|
+
# remove the confirmed duplicated objects if the process fails
|
|
314
|
+
# do not use Dashboard::BulkDeleteCascade here as it may remove datasets from the source dashboard as well
|
|
315
|
+
def remove_duplicated_objects
|
|
316
|
+
logger.info "Removing duplicated objects ..."
|
|
317
|
+
|
|
318
|
+
new_dataset_ids = dataset_duplication_tracker&.map { |dataset| dataset[:new_dataset_id] }.compact
|
|
319
|
+
Superset::Dataset::BulkDelete.new(dataset_ids: new_dataset_ids).perform if new_dataset_ids.any?
|
|
320
|
+
|
|
321
|
+
new_chart_ids = new_charts_list&.map { |r| r['id'] }.compact
|
|
322
|
+
Superset::Chart::BulkDelete.new(chart_ids: new_chart_ids).perform if new_chart_ids.any?
|
|
323
|
+
|
|
324
|
+
Superset::Dashboard::Delete.new(dashboard_id: new_dashboard.id).perform if new_dashboard.id.present?
|
|
325
|
+
logger.info "Removed duplicated objects successfully."
|
|
326
|
+
end
|
|
327
|
+
|
|
293
328
|
def logger
|
|
294
329
|
@logger ||= Superset::Logger.new
|
|
295
330
|
end
|
|
@@ -4,11 +4,11 @@ module Superset
|
|
|
4
4
|
module Tag
|
|
5
5
|
class AddToObject < Superset::Request
|
|
6
6
|
|
|
7
|
-
attr_reader :object_type_id, :
|
|
7
|
+
attr_reader :object_type_id, :target_id, :tags
|
|
8
8
|
|
|
9
|
-
def initialize(object_type_id:,
|
|
9
|
+
def initialize(object_type_id:, target_id:, tags: [])
|
|
10
10
|
@object_type_id = object_type_id
|
|
11
|
-
@
|
|
11
|
+
@target_id = target_id
|
|
12
12
|
@tags = tags
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -31,7 +31,7 @@ module Superset
|
|
|
31
31
|
def validate_constructor_args
|
|
32
32
|
raise InvalidParameterError, "object_type_id integer is required" unless object_type_id.present? && object_type_id.is_a?(Integer)
|
|
33
33
|
raise InvalidParameterError, "object_type_id is not a known value" unless ObjectType.list.include?(object_type_id)
|
|
34
|
-
raise InvalidParameterError, "
|
|
34
|
+
raise InvalidParameterError, "target_id integer is required" unless target_id.present? && target_id.is_a?(Integer)
|
|
35
35
|
raise InvalidParameterError, "tags array is required" unless tags.present? && tags.is_a?(Array)
|
|
36
36
|
raise InvalidParameterError, "tags array must contain string only values" unless tags.all? { |item| item.is_a?(String) }
|
|
37
37
|
end
|
|
@@ -39,7 +39,7 @@ module Superset
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
41
|
def route
|
|
42
|
-
"tag/#{object_type_id}/#{
|
|
42
|
+
"tag/#{object_type_id}/#{target_id}/"
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
data/lib/superset/version.rb
CHANGED
data/superset.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
|
11
11
|
spec.summary = "A Ruby Client for Apache Superset API"
|
|
12
12
|
spec.homepage = "https://github.com/rdytech/superset-client"
|
|
13
13
|
spec.license = "MIT"
|
|
14
|
-
spec.required_ruby_version = ">=
|
|
14
|
+
spec.required_ruby_version = ">= 3"
|
|
15
15
|
|
|
16
16
|
#spec.metadata["allowed_push_host"] = ""
|
|
17
17
|
|
|
@@ -34,21 +34,20 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
"lib"
|
|
35
35
|
]
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
spec.add_dependency "dotenv", "~> 2.7"
|
|
39
|
-
spec.add_dependency "json", "~> 2.6"
|
|
37
|
+
spec.add_dependency "json", ">= 2.0"
|
|
40
38
|
spec.add_dependency "terminal-table", "~> 4.0"
|
|
41
|
-
spec.add_dependency "
|
|
42
|
-
spec.add_dependency "
|
|
43
|
-
spec.add_dependency "require_all", "~> 3.0"
|
|
44
|
-
spec.add_dependency "rubyzip", "~> 1.0"
|
|
39
|
+
spec.add_dependency "require_all", ">= 3.0"
|
|
40
|
+
spec.add_dependency "rubyzip", ">= 1.3"
|
|
45
41
|
spec.add_dependency "faraday", "~> 1.0"
|
|
46
42
|
spec.add_dependency "faraday-multipart", "~> 1.0"
|
|
47
|
-
spec.add_dependency "enumerate_it", "
|
|
48
|
-
|
|
49
|
-
spec.add_development_dependency "
|
|
50
|
-
spec.add_development_dependency "
|
|
51
|
-
spec.add_development_dependency "
|
|
43
|
+
spec.add_dependency "enumerate_it", ">= 1.7"
|
|
44
|
+
|
|
45
|
+
spec.add_development_dependency "dotenv", ">= 2.0"
|
|
46
|
+
spec.add_development_dependency "rake", ">= 13.0"
|
|
47
|
+
spec.add_development_dependency "rspec", ">= 3.0"
|
|
48
|
+
spec.add_development_dependency "rubocop", ">= 1.0"
|
|
49
|
+
spec.add_development_dependency "pry", ">= 0.14"
|
|
50
|
+
spec.add_development_dependency "rollbar", ">= 3.0"
|
|
52
51
|
|
|
53
52
|
# For more information and examples about making a new gem, check out our
|
|
54
53
|
# guide at: https://bundler.io/guides/creating_gem.html
|
metadata
CHANGED
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: superset
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jbat
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: dotenv
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '2.7'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '2.7'
|
|
27
12
|
- !ruby/object:Gem::Dependency
|
|
28
13
|
name: json
|
|
29
14
|
requirement: !ruby/object:Gem::Requirement
|
|
30
15
|
requirements:
|
|
31
|
-
- - "
|
|
16
|
+
- - ">="
|
|
32
17
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '2.
|
|
18
|
+
version: '2.0'
|
|
34
19
|
type: :runtime
|
|
35
20
|
prerelease: false
|
|
36
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
22
|
requirements:
|
|
38
|
-
- - "
|
|
23
|
+
- - ">="
|
|
39
24
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '2.
|
|
25
|
+
version: '2.0'
|
|
41
26
|
- !ruby/object:Gem::Dependency
|
|
42
27
|
name: terminal-table
|
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -53,49 +38,49 @@ dependencies:
|
|
|
53
38
|
- !ruby/object:Gem::Version
|
|
54
39
|
version: '4.0'
|
|
55
40
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
41
|
+
name: require_all
|
|
57
42
|
requirement: !ruby/object:Gem::Requirement
|
|
58
43
|
requirements:
|
|
59
|
-
- - "
|
|
44
|
+
- - ">="
|
|
60
45
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
46
|
+
version: '3.0'
|
|
62
47
|
type: :runtime
|
|
63
48
|
prerelease: false
|
|
64
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
50
|
requirements:
|
|
66
|
-
- - "
|
|
51
|
+
- - ">="
|
|
67
52
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
53
|
+
version: '3.0'
|
|
69
54
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
55
|
+
name: rubyzip
|
|
71
56
|
requirement: !ruby/object:Gem::Requirement
|
|
72
57
|
requirements:
|
|
73
|
-
- - "
|
|
58
|
+
- - ">="
|
|
74
59
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3
|
|
60
|
+
version: '1.3'
|
|
76
61
|
type: :runtime
|
|
77
62
|
prerelease: false
|
|
78
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
64
|
requirements:
|
|
80
|
-
- - "
|
|
65
|
+
- - ">="
|
|
81
66
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '3
|
|
67
|
+
version: '1.3'
|
|
83
68
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
69
|
+
name: faraday
|
|
85
70
|
requirement: !ruby/object:Gem::Requirement
|
|
86
71
|
requirements:
|
|
87
72
|
- - "~>"
|
|
88
73
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
74
|
+
version: '1.0'
|
|
90
75
|
type: :runtime
|
|
91
76
|
prerelease: false
|
|
92
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
78
|
requirements:
|
|
94
79
|
- - "~>"
|
|
95
80
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
81
|
+
version: '1.0'
|
|
97
82
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
83
|
+
name: faraday-multipart
|
|
99
84
|
requirement: !ruby/object:Gem::Requirement
|
|
100
85
|
requirements:
|
|
101
86
|
- - "~>"
|
|
@@ -109,90 +94,103 @@ dependencies:
|
|
|
109
94
|
- !ruby/object:Gem::Version
|
|
110
95
|
version: '1.0'
|
|
111
96
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
97
|
+
name: enumerate_it
|
|
113
98
|
requirement: !ruby/object:Gem::Requirement
|
|
114
99
|
requirements:
|
|
115
|
-
- - "
|
|
100
|
+
- - ">="
|
|
116
101
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '1.
|
|
102
|
+
version: '1.7'
|
|
118
103
|
type: :runtime
|
|
119
104
|
prerelease: false
|
|
120
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
106
|
requirements:
|
|
122
|
-
- - "
|
|
107
|
+
- - ">="
|
|
123
108
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '1.
|
|
109
|
+
version: '1.7'
|
|
125
110
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
111
|
+
name: dotenv
|
|
127
112
|
requirement: !ruby/object:Gem::Requirement
|
|
128
113
|
requirements:
|
|
129
|
-
- - "
|
|
114
|
+
- - ">="
|
|
130
115
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
132
|
-
type: :
|
|
116
|
+
version: '2.0'
|
|
117
|
+
type: :development
|
|
133
118
|
prerelease: false
|
|
134
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
120
|
requirements:
|
|
136
|
-
- - "
|
|
121
|
+
- - ">="
|
|
137
122
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
123
|
+
version: '2.0'
|
|
139
124
|
- !ruby/object:Gem::Dependency
|
|
140
|
-
name:
|
|
125
|
+
name: rake
|
|
141
126
|
requirement: !ruby/object:Gem::Requirement
|
|
142
127
|
requirements:
|
|
143
|
-
- - "
|
|
128
|
+
- - ">="
|
|
144
129
|
- !ruby/object:Gem::Version
|
|
145
|
-
version:
|
|
146
|
-
type: :
|
|
130
|
+
version: '13.0'
|
|
131
|
+
type: :development
|
|
147
132
|
prerelease: false
|
|
148
133
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
134
|
requirements:
|
|
150
|
-
- - "
|
|
135
|
+
- - ">="
|
|
151
136
|
- !ruby/object:Gem::Version
|
|
152
|
-
version:
|
|
137
|
+
version: '13.0'
|
|
153
138
|
- !ruby/object:Gem::Dependency
|
|
154
139
|
name: rspec
|
|
155
140
|
requirement: !ruby/object:Gem::Requirement
|
|
156
141
|
requirements:
|
|
157
|
-
- - "
|
|
142
|
+
- - ">="
|
|
158
143
|
- !ruby/object:Gem::Version
|
|
159
144
|
version: '3.0'
|
|
160
145
|
type: :development
|
|
161
146
|
prerelease: false
|
|
162
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
148
|
requirements:
|
|
164
|
-
- - "
|
|
149
|
+
- - ">="
|
|
165
150
|
- !ruby/object:Gem::Version
|
|
166
151
|
version: '3.0'
|
|
167
152
|
- !ruby/object:Gem::Dependency
|
|
168
153
|
name: rubocop
|
|
169
154
|
requirement: !ruby/object:Gem::Requirement
|
|
170
155
|
requirements:
|
|
171
|
-
- - "
|
|
156
|
+
- - ">="
|
|
172
157
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: '1.
|
|
158
|
+
version: '1.0'
|
|
174
159
|
type: :development
|
|
175
160
|
prerelease: false
|
|
176
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
162
|
requirements:
|
|
178
|
-
- - "
|
|
163
|
+
- - ">="
|
|
179
164
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: '1.
|
|
165
|
+
version: '1.0'
|
|
181
166
|
- !ruby/object:Gem::Dependency
|
|
182
167
|
name: pry
|
|
183
168
|
requirement: !ruby/object:Gem::Requirement
|
|
184
169
|
requirements:
|
|
185
|
-
- - "
|
|
170
|
+
- - ">="
|
|
186
171
|
- !ruby/object:Gem::Version
|
|
187
172
|
version: '0.14'
|
|
188
173
|
type: :development
|
|
189
174
|
prerelease: false
|
|
190
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
176
|
requirements:
|
|
192
|
-
- - "
|
|
177
|
+
- - ">="
|
|
193
178
|
- !ruby/object:Gem::Version
|
|
194
179
|
version: '0.14'
|
|
195
|
-
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: rollbar
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '3.0'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - ">="
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '3.0'
|
|
196
194
|
email:
|
|
197
195
|
- jonathon.batson@gmail.com
|
|
198
196
|
executables: []
|
|
@@ -233,6 +231,7 @@ files:
|
|
|
233
231
|
- lib/superset/credential/embedded_user.rb
|
|
234
232
|
- lib/superset/dashboard/bulk_delete.rb
|
|
235
233
|
- lib/superset/dashboard/bulk_delete_cascade.rb
|
|
234
|
+
- lib/superset/dashboard/cascade_ownership/add_new_owner.rb
|
|
236
235
|
- lib/superset/dashboard/charts/list.rb
|
|
237
236
|
- lib/superset/dashboard/compare.rb
|
|
238
237
|
- lib/superset/dashboard/copy.rb
|
|
@@ -293,7 +292,6 @@ homepage: https://github.com/rdytech/superset-client
|
|
|
293
292
|
licenses:
|
|
294
293
|
- MIT
|
|
295
294
|
metadata: {}
|
|
296
|
-
post_install_message:
|
|
297
295
|
rdoc_options: []
|
|
298
296
|
require_paths:
|
|
299
297
|
- lib
|
|
@@ -301,15 +299,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
301
299
|
requirements:
|
|
302
300
|
- - ">="
|
|
303
301
|
- !ruby/object:Gem::Version
|
|
304
|
-
version:
|
|
302
|
+
version: '3'
|
|
305
303
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
306
304
|
requirements:
|
|
307
305
|
- - ">="
|
|
308
306
|
- !ruby/object:Gem::Version
|
|
309
307
|
version: '0'
|
|
310
308
|
requirements: []
|
|
311
|
-
rubygems_version: 3.
|
|
312
|
-
signing_key:
|
|
309
|
+
rubygems_version: 3.6.7
|
|
313
310
|
specification_version: 4
|
|
314
311
|
summary: A Ruby Client for Apache Superset API
|
|
315
312
|
test_files: []
|