Merge pull request #192 from coreos-inc/sqlssl
Allow SSL cert for the database to be configured
This commit is contained in:
commit
756d6784ca
8 changed files with 45 additions and 12 deletions
|
@ -84,10 +84,11 @@ db_random_func = CallableProxy()
|
||||||
db_for_update = CallableProxy()
|
db_for_update = CallableProxy()
|
||||||
|
|
||||||
|
|
||||||
def validate_database_url(url, connect_timeout=5):
|
def validate_database_url(url, db_kwargs, connect_timeout=5):
|
||||||
driver = _db_from_url(url, {
|
db_kwargs = db_kwargs.copy()
|
||||||
'connect_timeout': connect_timeout
|
db_kwargs['connect_timeout'] = connect_timeout
|
||||||
})
|
|
||||||
|
driver = _db_from_url(url, db_kwargs)
|
||||||
driver.connect()
|
driver.connect()
|
||||||
driver.close()
|
driver.close()
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,9 @@ class SuperUserConfigFile(ApiResource):
|
||||||
if not filename in CONFIG_FILENAMES:
|
if not filename in CONFIG_FILENAMES:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if SuperUserPermission().can():
|
# Note: This method can be called before the configuration exists
|
||||||
|
# to upload the database SSL cert.
|
||||||
|
if not CONFIG_PROVIDER.yaml_exists() or SuperUserPermission().can():
|
||||||
uploaded_file = request.files['file']
|
uploaded_file = request.files['file']
|
||||||
if not uploaded_file:
|
if not uploaded_file:
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="config-file-field-element">
|
<div class="config-file-field-element">
|
||||||
<span ng-show="uploadProgress == null">
|
<span ng-show="uploadProgress == null">
|
||||||
<span ng-if="hasFile"><code>{{ filename }}</code></span>
|
<span ng-if="hasFile"><code>{{ filename }}</code></span>
|
||||||
<span class="nofile" ng-if="!hasFile"><code>{{ filename }}</code> not found in mounted config directory: </span>
|
<span class="nofile" ng-if="!hasFile && skipCheckFile != 'true'"><code>{{ filename }}</code> not found in mounted config directory: </span>
|
||||||
<input type="file" ng-file-select="onFileSelect($files)">
|
<input type="file" ng-file-select="onFileSelect($files)">
|
||||||
</span>
|
</span>
|
||||||
<span ng-show="uploadProgress != null">
|
<span ng-show="uploadProgress != null">
|
||||||
|
|
|
@ -591,13 +591,18 @@ angular.module("core-config-setup", ['angularFileUpload'])
|
||||||
transclude: false,
|
transclude: false,
|
||||||
restrict: 'C',
|
restrict: 'C',
|
||||||
scope: {
|
scope: {
|
||||||
'filename': '@filename'
|
'filename': '@filename',
|
||||||
|
'skipCheckFile': '@skipCheckFile',
|
||||||
|
'hasFile': '=hasFile'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Restangular, $upload) {
|
controller: function($scope, $element, Restangular, $upload) {
|
||||||
$scope.hasFile = false;
|
$scope.hasFile = false;
|
||||||
|
|
||||||
$scope.onFileSelect = function(files) {
|
$scope.onFileSelect = function(files) {
|
||||||
if (files.length < 1) { return; }
|
if (files.length < 1) {
|
||||||
|
$scope.hasFile = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.uploadProgress = 0;
|
$scope.uploadProgress = 0;
|
||||||
$scope.upload = $upload.upload({
|
$scope.upload = $upload.upload({
|
||||||
|
@ -623,7 +628,7 @@ angular.module("core-config-setup", ['angularFileUpload'])
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($scope.filename) {
|
if ($scope.filename && $scope.skipCheckFile != "true") {
|
||||||
loadStatus($scope.filename);
|
loadStatus($scope.filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,9 @@
|
||||||
$scope.stepProgress = [];
|
$scope.stepProgress = [];
|
||||||
$scope.hasSSL = false;
|
$scope.hasSSL = false;
|
||||||
$scope.hostname = null;
|
$scope.hostname = null;
|
||||||
|
$scope.currentState = {
|
||||||
|
'hasDatabaseSSLCert': false
|
||||||
|
};
|
||||||
|
|
||||||
$scope.$watch('currentStep', function(currentStep) {
|
$scope.$watch('currentStep', function(currentStep) {
|
||||||
$scope.stepProgress = $scope.getProgress(currentStep);
|
$scope.stepProgress = $scope.getProgress(currentStep);
|
||||||
|
@ -268,6 +271,14 @@
|
||||||
'hostname': window.location.host
|
'hostname': window.location.host
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ($scope.currentState.hasDatabaseSSLCert) {
|
||||||
|
data['config']['DB_CONNECTION_ARGS'] = {
|
||||||
|
'ssl': {
|
||||||
|
'ca': 'conf/stack/database.pem'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
'service': 'database'
|
'service': 'database'
|
||||||
};
|
};
|
||||||
|
|
|
@ -192,6 +192,14 @@
|
||||||
placeholder="registry-database"></span>
|
placeholder="registry-database"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr ng-show="fields.kind">
|
||||||
|
<td>SSL Certificate:</td>
|
||||||
|
<td>
|
||||||
|
<span class="config-file-field" filename="database.pem"
|
||||||
|
skip-check-file="true" has-file="currentState.hasDatabaseSSLCert"></span>
|
||||||
|
<div class="help-text">Optional SSL certicate (in PEM format) to use to connect to the database</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -47,7 +47,13 @@ class TestSuperUserConfigFile(ApiTestCase):
|
||||||
|
|
||||||
def test_post_non_superuser(self):
|
def test_post_non_superuser(self):
|
||||||
with ConfigForTesting():
|
with ConfigForTesting():
|
||||||
# No user.
|
# No user, before config.yaml exists.
|
||||||
|
self.postResponse(SuperUserConfigFile, params=dict(filename='ssl.cert'), expected_code=400)
|
||||||
|
|
||||||
|
# Write some config.
|
||||||
|
self.putJsonResponse(SuperUserConfig, data=dict(config={}, hostname='foobar'))
|
||||||
|
|
||||||
|
# No user, with config.yaml.
|
||||||
self.postResponse(SuperUserConfigFile, params=dict(filename='ssl.cert'), expected_code=403)
|
self.postResponse(SuperUserConfigFile, params=dict(filename='ssl.cert'), expected_code=403)
|
||||||
|
|
||||||
# Non-superuser.
|
# Non-superuser.
|
||||||
|
|
|
@ -20,7 +20,7 @@ from app import app, CONFIG_PROVIDER, get_app_url, OVERRIDE_CONFIG_DIRECTORY
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
SSL_FILENAMES = ['ssl.cert', 'ssl.key']
|
SSL_FILENAMES = ['ssl.cert', 'ssl.key', 'database.pem']
|
||||||
JWT_FILENAMES = ['jwt-authn.cert']
|
JWT_FILENAMES = ['jwt-authn.cert']
|
||||||
CONFIG_FILENAMES = SSL_FILENAMES + JWT_FILENAMES
|
CONFIG_FILENAMES = SSL_FILENAMES + JWT_FILENAMES
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ def validate_service_for_config(service, config, password=None):
|
||||||
def _validate_database(config, _):
|
def _validate_database(config, _):
|
||||||
""" Validates connecting to the database. """
|
""" Validates connecting to the database. """
|
||||||
try:
|
try:
|
||||||
validate_database_url(config['DB_URI'])
|
validate_database_url(config['DB_URI'], config.get('DB_CONNECTION_ARGS', {}))
|
||||||
except peewee.OperationalError as ex:
|
except peewee.OperationalError as ex:
|
||||||
if ex.args and len(ex.args) > 1:
|
if ex.args and len(ex.args) > 1:
|
||||||
raise Exception(ex.args[1])
|
raise Exception(ex.args[1])
|
||||||
|
|
Reference in a new issue