Read tarball into in-memory config provider
This commit is contained in:
parent
8aa18a29a8
commit
bb2b28cd11
5 changed files with 83 additions and 9 deletions
|
@ -1,4 +1,6 @@
|
|||
import logging
|
||||
import tarfile
|
||||
import cStringIO
|
||||
|
||||
from flask import request, make_response
|
||||
|
||||
|
@ -17,9 +19,10 @@ class TarConfigLoader(ApiResource):
|
|||
input_stream = request.stream
|
||||
|
||||
# since we're working with a tar file, shouldn't be larger than ~20KB, so just read the whole thing into mem
|
||||
buf = input_stream.read(-1)
|
||||
buf = input_stream.read()
|
||||
config = tarfile.open(mode="r:gz", fileobj=cStringIO.StringIO(buf))
|
||||
|
||||
# TODO(sam): refactor config provider to accept a stream write to avoid loading into memory
|
||||
config_provider.write_volume_file('test_tar.tar.gz', buf)
|
||||
config_provider.load_from_tarball(config)
|
||||
|
||||
return make_response('OK')
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
from config_app.config_util.config.fileprovider import FileConfigProvider
|
||||
from config_app.config_util.config.testprovider import TestConfigProvider
|
||||
from config_app.config_util.config.inmemoryprovider import InMemoryProvider
|
||||
|
||||
|
||||
def get_config_provider(config_volume, yaml_filename, py_filename, testing=False):
|
||||
""" Loads and returns the config provider for the current environment. """
|
||||
if True:
|
||||
return InMemoryProvider()
|
||||
|
||||
if testing:
|
||||
return TestConfigProvider()
|
||||
|
||||
|
|
66
config_app/config_util/config/inmemoryprovider.py
Normal file
66
config_app/config_util/config/inmemoryprovider.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
import logging
|
||||
import yaml
|
||||
|
||||
from config_app.config_util.config.baseprovider import BaseProvider
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_FILENAME = 'config.yaml'
|
||||
|
||||
class InMemoryProvider(BaseProvider):
|
||||
def __init__(self):
|
||||
self.files = {}
|
||||
self.config = {}
|
||||
|
||||
@property
|
||||
def provider_id(self):
|
||||
return 'memory'
|
||||
|
||||
def update_app_config(self, app_config):
|
||||
self.config = app_config
|
||||
|
||||
def get_config(self):
|
||||
return self.config
|
||||
|
||||
def save_config(self, config_object):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def config_exists(self):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def volume_exists(self):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def volume_file_exists(self, filename):
|
||||
return filename in self.files
|
||||
|
||||
def get_volume_file(self, filename, mode='r'):
|
||||
return self.files[filename]
|
||||
|
||||
def write_volume_file(self, filename, contents):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def remove_volume_file(self, filename):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def list_volume_directory(self, path):
|
||||
return [ name for name in self.files ]
|
||||
|
||||
def save_volume_file(self, filename, flask_file):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def requires_restart(self, app_config):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def get_volume_path(self, directory, filename):
|
||||
raise Exception('Not implemented yet')
|
||||
|
||||
def load_from_tarball(self, tarfile):
|
||||
for tarinfo in tarfile.getmembers():
|
||||
if tarinfo.isfile():
|
||||
if tarinfo.name == CONFIG_FILENAME:
|
||||
self.config = yaml.load(tarfile.extractfile(tarinfo.name).read())
|
||||
else:
|
||||
self.files[tarinfo.name] = tarfile.extractfile(tarinfo.name).read()
|
||||
|
|
@ -8,7 +8,7 @@ const styleUrl = require('./load-config.css');
|
|||
styleUrls: [ styleUrl ],
|
||||
})
|
||||
export class LoadConfigComponent {
|
||||
private isReady: boolean = false;
|
||||
private readyToSubmit: boolean = false;
|
||||
private uploadFunc: Function;
|
||||
private state: 'load' | 'validate' = 'load';
|
||||
|
||||
|
@ -16,12 +16,12 @@ export class LoadConfigComponent {
|
|||
}
|
||||
|
||||
private handleTarballSelected(files: File[], callback: Function) {
|
||||
this.isReady = true;
|
||||
this.readyToSubmit = true;
|
||||
callback(true)
|
||||
}
|
||||
|
||||
private handleTarballCleared() {
|
||||
this.isReady = false;
|
||||
this.readyToSubmit = false;
|
||||
}
|
||||
|
||||
private uploadTarball() {
|
||||
|
@ -30,7 +30,8 @@ export class LoadConfigComponent {
|
|||
this.state = 'validate';
|
||||
}
|
||||
else {
|
||||
this.apiService.errorDisplay('Could not upload configuration. Please reload the page and try again.\n' +
|
||||
this.apiService.errorDisplay('Error loading configuration',
|
||||
'Could not upload configuration. Please reload the page and try again.\n' +
|
||||
'If this problem persists, please contact support')();
|
||||
}
|
||||
});
|
||||
|
@ -42,7 +43,7 @@ export class LoadConfigComponent {
|
|||
* @param files: files to upload
|
||||
* @param uploadFiles: function to call to upload files
|
||||
*/
|
||||
private filesValidated(files, uploadFiles) {
|
||||
private tarballValidatedByUploadBox(files, uploadFiles) {
|
||||
this.uploadFunc = uploadFiles;
|
||||
}
|
||||
}
|
|
@ -14,11 +14,11 @@
|
|||
select-message="Select a previous configuration to modify. Must be in tar.gz format"
|
||||
files-selected="$ctrl.handleTarballSelected(files, callback)"
|
||||
files-cleared="$ctrl.handleFilesCleared()"
|
||||
files-validated="$ctrl.filesValidated(files, uploadFiles)"
|
||||
files-validated="$ctrl.tarballValidatedByUploadBox(files, uploadFiles)"
|
||||
extensions="['application/gzip', '.gz']"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" ng-click="$ctrl.uploadTarball()" ng-disabled="!$ctrl.isReady">
|
||||
<button type="button" class="btn btn-primary" ng-click="$ctrl.uploadTarball()" ng-disabled="!$ctrl.readyToSubmit">
|
||||
Upload Configuration
|
||||
</button>
|
||||
</div>
|
||||
|
|
Reference in a new issue