From 01b59e8d66c5efbd8c2124667d32e1053aa1b16b Mon Sep 17 00:00:00 2001 From: Evan Cordell Date: Wed, 17 May 2017 08:12:09 -0400 Subject: [PATCH] ConfigProviders abstract over path construction Fixes issue where certs can't be uploaded in UI in k8s --- endpoints/api/superuser.py | 6 +++--- util/config/provider/baseprovider.py | 5 +++++ util/config/provider/fileprovider.py | 3 +++ util/config/provider/k8sprovider.py | 16 ++++++++++++++++ util/config/provider/testprovider.py | 5 +++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/endpoints/api/superuser.py b/endpoints/api/superuser.py index 356193308..dcecf6ea0 100644 --- a/endpoints/api/superuser.py +++ b/endpoints/api/superuser.py @@ -852,7 +852,7 @@ class SuperUserCustomCertificates(ApiResource): cert_views = [] for extra_cert_path in extra_certs_found: try: - cert_full_path = os.path.join(EXTRA_CA_DIRECTORY, extra_cert_path) + cert_full_path = config_provider.get_volume_path(EXTRA_CA_DIRECTORY, extra_cert_path) with config_provider.get_volume_file(cert_full_path) as f: certificate = load_certificate(f.read()) cert_views.append({ @@ -900,7 +900,7 @@ class SuperUserCustomCertificate(ApiResource): abort(400) logger.debug('Saving custom certificate %s', certpath) - cert_full_path = os.path.join(EXTRA_CA_DIRECTORY, certpath) + cert_full_path = config_provider.get_volume_path(EXTRA_CA_DIRECTORY, certpath) config_provider.save_volume_file(cert_full_path, uploaded_file) logger.debug('Saved custom certificate %s', certpath) @@ -934,7 +934,7 @@ class SuperUserCustomCertificate(ApiResource): @verify_not_prod def delete(self, certpath): if SuperUserPermission().can(): - cert_full_path = os.path.join(EXTRA_CA_DIRECTORY, certpath) + cert_full_path = config_provider.get_volume_path(EXTRA_CA_DIRECTORY, certpath) config_provider.remove_volume_file(cert_full_path) return '', 204 diff --git a/util/config/provider/baseprovider.py b/util/config/provider/baseprovider.py index e5af29fa4..91ac64f74 100644 --- a/util/config/provider/baseprovider.py +++ b/util/config/provider/baseprovider.py @@ -109,6 +109,11 @@ class BaseProvider(object): indicating that this container requires a restart. """ raise NotImplementedError + + def get_volume_path(self, directory, file): + """ Helper for constructing file paths, which may differ between providers. For example, + kubernetes can't have subfolders in configmaps """ + raise NotImplementedError def _get_license_file(self): """ Returns the contents of the license file. """ diff --git a/util/config/provider/fileprovider.py b/util/config/provider/fileprovider.py index fdaf860b0..1cefa9794 100644 --- a/util/config/provider/fileprovider.py +++ b/util/config/provider/fileprovider.py @@ -110,3 +110,6 @@ class FileConfigProvider(BaseProvider): return True return False + + def get_volume_path(self, directory, file): + return os.path.join(directory, file) diff --git a/util/config/provider/k8sprovider.py b/util/config/provider/k8sprovider.py index 0feb6ca60..743892822 100644 --- a/util/config/provider/k8sprovider.py +++ b/util/config/provider/k8sprovider.py @@ -54,6 +54,19 @@ class KubernetesConfigProvider(FileConfigProvider): self._update_secret_file(filename, contents) except IOError as ioe: raise CannotWriteConfigException(str(ioe)) + + def volume_file_exists(self, filename): + secret = self._lookup_secret() + return filename in secret + + + def list_volume_directory(self, path): + secret = self._lookup_secret() + + paths = [] + for filename in secret: + if filename.startswith(path): + paths.append(filename[len(path) + 1:]) def remove_volume_file(self, filename): super(KubernetesConfigProvider, self).remove_volume_file(filename) @@ -130,3 +143,6 @@ class KubernetesConfigProvider(FileConfigProvider): request = Request(method, url, data=data, headers=headers) return session.send(request.prepare(), verify=False, timeout=2) + + def get_volume_path(self, directory, file): + return "_".join([directory, file]) \ No newline at end of file diff --git a/util/config/provider/testprovider.py b/util/config/provider/testprovider.py index bae362bda..d0a81e550 100644 --- a/util/config/provider/testprovider.py +++ b/util/config/provider/testprovider.py @@ -1,5 +1,6 @@ import json import io +import os from datetime import datetime, timedelta from util.config.provider.baseprovider import BaseProvider @@ -88,3 +89,7 @@ class TestConfigProvider(BaseProvider): def reset_for_test(self): self._config['SUPER_USERS'] = ['devtable'] self.files = {} + + def get_volume_path(self, directory, file): + return os.path.join(directory, file) +