Skip to content

Commit 759906d

Browse files
committed
add validation check to confirm database connection exists
1 parent fecd1fa commit 759906d

File tree

6 files changed

+101
-25
lines changed

6 files changed

+101
-25
lines changed

lib/superset/dashboard/import.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
module Superset
2121
module Dashboard
2222
class Import < Request
23-
2423
attr_reader :source_zip_file, :overwrite
2524

2625
def initialize(source_zip_file: , overwrite: true)
@@ -30,7 +29,6 @@ def initialize(source_zip_file: , overwrite: true)
3029

3130
def perform
3231
validate_params
33-
3432
response
3533
end
3634

@@ -46,7 +44,9 @@ def response
4644
def validate_params
4745
raise ArgumentError, 'source_zip_file is required' if source_zip_file.nil?
4846
raise ArgumentError, 'source_zip_file does not exist' unless File.exist?(source_zip_file)
47+
raise ArgumentError, 'source_zip_file is not a zip file' unless File.extname(source_zip_file) == '.zip'
4948
raise ArgumentError, 'overwrite must be a boolean' unless [true, false].include?(overwrite)
49+
raise ArgumentError, "zip target database does not exist: #{zip_database_config_not_found_in_superset}" if zip_database_config_not_found_in_superset.present?
5050
end
5151

5252
def payload
@@ -59,6 +59,26 @@ def payload
5959
def route
6060
"dashboard/import/"
6161
end
62+
63+
def zip_database_config_not_found_in_superset
64+
zip_databases_details.select {|s| !superset_database_uuids_found.include?(s[:uuid]) }
65+
end
66+
67+
def superset_database_uuids_found
68+
@superset_database_uuids_found ||= begin
69+
zip_databases_details.map {|i| i[:uuid]}.map do |uuid|
70+
uuid if Superset::Database::List.new(uuid_equals: uuid).result.count == 1
71+
end.compact
72+
end
73+
end
74+
75+
def zip_databases_details
76+
zip_dashboard_config[:databases].map{|d| {uuid: d[:content][:uuid], name: d[:content][:database_name]} }
77+
end
78+
79+
def zip_dashboard_config
80+
@zip_dashboard_config ||= Superset::Services::DashboardLoader.new(dashboard_export_zip: source_zip_file).perform
81+
end
6282
end
6383
end
6484
end

lib/superset/database/list.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
module Superset
55
module Database
66
class List < Superset::Request
7-
attr_reader :title_contains
7+
attr_reader :title_contains, :uuid_equals
88

9-
def initialize(page_num: 0, title_contains: '')
9+
def initialize(page_num: 0, title_contains: '', uuid_equals: '')
1010
@title_contains = title_contains
11+
@uuid_equals = uuid_equals
1112
super(page_num: page_num)
1213
end
1314

@@ -34,6 +35,7 @@ def filters
3435
# TODO filtering across all list classes can be refactored to support multiple options in a more flexible way
3536
filter_set = []
3637
filter_set << "(col:database_name,opr:ct,value:'#{title_contains}')" if title_contains.present?
38+
filter_set << "(col:uuid,opr:eq,value:'#{uuid_equals}')" if uuid_equals.present?
3739
unless filter_set.empty?
3840
"filters:!(" + filter_set.join(',') + "),"
3941
end
@@ -45,6 +47,7 @@ def list_attributes
4547

4648
def validate_constructor_args
4749
raise InvalidParameterError, "title_contains must be a String type" unless title_contains.is_a?(String)
50+
raise InvalidParameterError, "uuid_equals must be a String type" unless uuid_equals.is_a?(String)
4851
end
4952
end
5053
end

lib/superset/request.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class Request
55
class InvalidParameterError < StandardError; end
66
class ValidationError < StandardError; end
77

8-
98
PAGE_SIZE = 100
109

1110
attr_accessor :page_num

lib/superset/services/import_dashboard_across_environment.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ def update_dataset_configs
8686
def create_new_dashboard_zip
8787
Zip::File.open(new_zip_file, Zip::File::CREATE) do |zipfile|
8888
Dir[File.join(dashboard_export_root_path, '**', '**')].each do |file|
89-
# puts "File Sub:" + file.sub(dashboard_export_root_path + '/', File.basename(dashboard_export_root_path) + '/' ).to_s
9089
zipfile.add(file.sub(dashboard_export_root_path + '/', File.basename(dashboard_export_root_path) + '/' ), file) if File.file?(file)
9190
end
9291
end

spec/superset/dashboard/import_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
describe '#response' do
1616
context 'with valid parameters' do
17+
before do
18+
allow(Superset::Database::List).to receive(:new).
19+
with(uuid_equals: "a2dc77af-e654-49bb-b321-40f6b559a1ee").
20+
and_return(double(result: ['some data']))
21+
end
1722

1823
specify 'returns response' do
1924
expect(subject.perform).to eq(response)
@@ -45,6 +50,26 @@
4550
expect { subject.perform }.to raise_error(ArgumentError, 'overwrite must be a boolean')
4651
end
4752
end
53+
54+
context 'when source_zip_file is not a zip extension' do
55+
let(:source_zip_file) { 'spec/fixtures/database-prod-examples.yaml' }
56+
57+
specify 'raises error' do
58+
expect { subject.perform }.to raise_error(ArgumentError, 'source_zip_file is not a zip file')
59+
end
60+
end
61+
62+
context 'when zip_database_config_not_found_in_superset is not present' do
63+
before do
64+
allow(Superset::Database::List).to receive(:new).
65+
with(uuid_equals: "a2dc77af-e654-49bb-b321-40f6b559a1ee").
66+
and_return(double(result: []))
67+
end
68+
69+
specify 'raises error' do
70+
expect { subject.perform }.to raise_error(ArgumentError, "zip target database does not exist: [{:uuid=>\"a2dc77af-e654-49bb-b321-40f6b559a1ee\", :name=>\"examples\"}]")
71+
end
72+
end
4873
end
4974
end
5075
end

spec/superset/database/list_spec.rb

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,30 @@
22

33
RSpec.describe Superset::Database::List do
44
subject { described_class.new }
5-
let(:result) do
6-
[
7-
{
8-
id: 1,
9-
database_name: 'Test 1',
10-
backend: 'postgres',
11-
expose_in_sqllab: 'true'
12-
},
13-
{
14-
id: 2,
15-
database_name: 'Test 2',
16-
backend: 'mysql',
17-
expose_in_sqllab: 'false'
18-
}
19-
]
20-
end
21-
22-
before do
23-
allow(subject).to receive(:result).and_return(result)
5+
let(:response) do
6+
{ 'result' =>
7+
[
8+
{
9+
id: 1,
10+
database_name: 'Test 1',
11+
backend: 'postgres',
12+
expose_in_sqllab: 'true'
13+
},
14+
{
15+
id: 2,
16+
database_name: 'Test 2',
17+
backend: 'mysql',
18+
expose_in_sqllab: 'false'
19+
}
20+
]
21+
}
2422
end
2523

2624
describe '#rows' do
25+
before do
26+
allow(subject).to receive(:response).and_return(response)
27+
end
28+
2729
specify do
2830
expect(subject.rows).to match_array(
2931
[
@@ -58,5 +60,33 @@
5860
expect(subject.query_params).to eq("filters:!((col:database_name,opr:ct,value:'acme')),page:0,page_size:100")
5961
end
6062
end
63+
64+
context 'with uuid_equals filters' do
65+
subject { described_class.new(uuid_equals: '123') }
66+
67+
specify do
68+
expect(subject.query_params).to eq("filters:!((col:uuid,opr:eq,value:'123')),page:0,page_size:100")
69+
end
70+
end
71+
end
72+
73+
describe '#response' do
74+
context 'with invalid parameters' do
75+
context 'when title_contains is not a string' do
76+
subject { described_class.new(title_contains: ['test']) }
77+
78+
specify do
79+
expect { subject.response }.to raise_error(Superset::Request::InvalidParameterError, 'title_contains must be a String type')
80+
end
81+
end
82+
83+
context 'when uuid_equals is not a string' do
84+
subject { described_class.new(uuid_equals: 1) }
85+
86+
specify do
87+
expect { subject.response }.to raise_error(Superset::Request::InvalidParameterError, 'uuid_equals must be a String type')
88+
end
89+
end
90+
end
6191
end
6292
end

0 commit comments

Comments
 (0)