Skip to content
Snippets Groups Projects
Commit 7ac9a7d7 authored by Cam Saül's avatar Cam Saül
Browse files

Merge pull request #392 from metabase/auto_infer_ssl

Infer SSL support automatically when adding a DB
parents 7af8cc8d df57a300
No related branches found
No related tags found
No related merge requests found
......@@ -49,6 +49,12 @@ DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$loc
$scope.ENGINES = CorvusCore.ENGINES;
// if we're adding a new database then hide the SSL field; we'll determine it automatically <3
var hideSSLField = true;
$scope.shouldHideField = function(field) {
return hideSSLField && field.fieldName === 'ssl';
};
// update an existing Database
var update = function(database, details) {
$scope.$broadcast("form:reset");
......@@ -73,11 +79,25 @@ DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$loc
});
};
// TODO - Why do we *require* a valid connection in setup, but not care about it here? :sob:
$scope.save = function(database, details) {
if ($routeParams.databaseId) {
update(database, details);
} else {
create(database, details);
// for a new DB we want to infer SSL support. First try to connect w/ SSL. If that fails, disable SSL
details.ssl = true;
// add 'engine' to the request body
details.engine = database.engine;
Metabase.validate_connection(details, function() {
console.log('Successfully connected with SSL. Setting SSL = true.');
create(database, details);
}, function() {
console.log('Unable to connect with SSL. Setting SSL = false.');
details.ssl = false;
create(database, details);
});
}
};
......@@ -101,6 +121,7 @@ DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$loc
Metabase.db_get({
'dbId': $routeParams.databaseId
}, function(database) {
hideSSLField = false;
$scope.database = database;
$scope.details = $scope.ENGINES[database.engine].parseDetails(database.details);
}, function(error) {
......@@ -116,9 +137,7 @@ DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$loc
engine: 'postgres',
details: {}
};
$scope.details = {
ssl: false
};
$scope.details = {};
}
}
]);
......
......@@ -14,9 +14,11 @@
<span class="Form-charm"></span>
</div>
<!-- Database Connection Info - Varies by Engine (details.*) -->
<!-- Database Connection Info Fields - Varies by Engine (details.*) -->
<div class="FormInputGroup">
<div class="Form-field" ng-repeat="field in ENGINES[database.engine].fields" mb-form-field="{{field.fieldName}}">
<!-- If the controller defines a delegate function shouldHideField() then we'll query that to determine whether each field should be shown
Otherwise we'll default to showing every field. This way we can hide 'advanced options' like SSL during the setup process -->
<div class="Form-field" ng-repeat="field in ENGINES[database.engine].fields" mb-form-field="{{field.fieldName}}" ng-if="!shouldHideField(field)">
<mb-form-label display-name="{{field.displayName}}" field-name="{{field.fieldName}}"></mb-form-label>
<!-- Multiple-Choice Field -->
<div ng-if="field.choices" class="Form-input Form-offset full Button-group">
......
......@@ -22,7 +22,13 @@ MetabaseServices.factory('Metabase', ['$resource', '$cookies', function($resourc
validate_connection: {
url:'/api/meta/db/validate/',
method:'POST',
headers: {'X-CSRFToken': function() { return $cookies.csrftoken; }}
headers: {'X-CSRFToken': function() { return $cookies.csrftoken; }},
transformRequest: function(data) {
// API expects 'port' to be an int :imp:
if (data.port) data.port = parseInt(data.port);
return angular.toJson(data);
}
},
db_get: {
url:'/api/meta/db/:dbId',
......
......@@ -841,7 +841,7 @@ CoreServices.factory('Session', ['$resource', '$cookies', function($resource, $c
ignoreAuthModule: true // this ensures a 401 response doesn't trigger another auth-required event
},
delete: {
method: 'DELETE',
method: 'DELETE'
},
forgot_password: {
url: '/api/session/forgot_password',
......
......@@ -87,8 +87,15 @@ SetupControllers.controller('SetupConnection', ['$scope', '$routeParams', '$loca
var newConnection = true;
$scope.breadcrumb = 'Add connection';
// hide the SSL field when creating a new DB until we auto-infer SSL support
var hideSSLField = true;
$scope.shouldHideField = function(field) {
return hideSSLField && field.fieldName === 'ssl';
};
if ($routeParams.dbId) {
newConnection = false;
hideSSLField = false;
Metabase.db_get({
'dbId': $routeParams.dbId
}, function(result) {
......@@ -114,44 +121,62 @@ SetupControllers.controller('SetupConnection', ['$scope', '$routeParams', '$loca
$scope.database.engine = engine;
};
// Call API to determine whether connection is valid. If so, save the DB.
$scope.submit = function() {
var engine = $scope.database.engine,
database = {
org: $scope.currentOrg.id,
name: $scope.database.name,
engine: engine,
details: $scope.ENGINES[engine].buildDetails($scope.details)
};
function success(result) {
$location.path('/setup/data');
}
function error(err) {
$scope.error = err;
console.log('error', err);
}
// add engine to the request body
$scope.details.engine = $scope.database.engine;
// api needs a int
if ($scope.details.port) {
$scope.details.port = parseInt($scope.details.port);
function validateConnectionDetails(onConnectionValidationFailed) {
console.log('attempting to connect with SSL set to: ', $scope.details.ssl);
Metabase.validate_connection($scope.details, function() {
// Connection valid, save the DB
console.log('connection successful.');
var engine = $scope.database.engine,
database = {
org: $scope.currentOrg.id,
name: $scope.database.name,
engine: engine,
details: $scope.ENGINES[engine].buildDetails($scope.details)
};
function onCreateOrUpdateDBSuccess(result) {
$location.path('/setup/data');
}
function onCreateOrUpdateDBError(err) {
$scope.error = err;
console.log('error', err);
}
if (newConnection) {
Metabase.db_create(database, onCreateOrUpdateDBSuccess, onCreateOrUpdateDBError);
} else {
// add the id since we're updating
database.id = $scope.database.id;
Metabase.db_update(database, onCreateOrUpdateDBSuccess, onCreateOrUpdateDBError);
}
}, onConnectionValidationFailed);
}
// Validate the connection string. Add engine to the request body
$scope.details.engine = $scope.database.engine;
Metabase.validate_connection($scope.details, function(result) {
if (newConnection) {
Metabase.db_create(database, success, error);
} else {
// add the id since we're updating
database.id = $scope.database.id;
Metabase.db_update(database, success, error);
}
}, function(error) {
function displayConnectionValidationError(error) {
console.log(error);
$scope.error = "Invalid Connection String - " + error.data.message;
});
}
// now perform the connection validation
if (newConnection) {
// if this is a new connection we'll try SSL first and if that fails we'll retry without it
$scope.details.ssl = true;
validateConnectionDetails(function(error) {
// try again without SSL
$scope.details.ssl = false;
validateConnectionDetails(displayConnectionValidationError);
});
} else {
validateConnectionDetails(displayConnectionValidationError);
}
};
}]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment