|
|
79af3c |
From c2a8008af30d045227058e3158e84c9415647760 Mon Sep 17 00:00:00 2001
|
|
|
79af3c |
From: Christian Heimes <cheimes@redhat.com>
|
|
|
79af3c |
Date: Fri, 31 Mar 2017 12:14:43 +0200
|
|
|
79af3c |
Subject: [PATCH 3/4] Remove etcd store
|
|
|
79af3c |
|
|
|
79af3c |
---
|
|
|
79af3c |
custodia/store/etcdstore.py | 123 -----------------------------------------
|
|
|
79af3c |
docs/source/plugins/stores.rst | 6 --
|
|
|
79af3c |
setup.py | 9 +--
|
|
|
79af3c |
3 files changed, 2 insertions(+), 136 deletions(-)
|
|
|
79af3c |
delete mode 100644 custodia/store/etcdstore.py
|
|
|
79af3c |
|
|
|
79af3c |
diff --git a/custodia/store/etcdstore.py b/custodia/store/etcdstore.py
|
|
|
79af3c |
deleted file mode 100644
|
|
|
79af3c |
index 759348b..0000000
|
|
|
79af3c |
--- a/custodia/store/etcdstore.py
|
|
|
79af3c |
+++ /dev/null
|
|
|
79af3c |
@@ -1,123 +0,0 @@
|
|
|
79af3c |
-# Copyright (C) 2015 Custodia Project Contributors - see LICENSE file
|
|
|
79af3c |
-
|
|
|
79af3c |
-from __future__ import print_function
|
|
|
79af3c |
-
|
|
|
79af3c |
-try:
|
|
|
79af3c |
- from etcd import (Client, EtcdException, EtcdNotFile, EtcdAlreadyExist,
|
|
|
79af3c |
- EtcdKeyNotFound)
|
|
|
79af3c |
-except ImportError:
|
|
|
79af3c |
- def Client(*args, **kwargs):
|
|
|
79af3c |
- raise RuntimeError("Etcd client is unavailable")
|
|
|
79af3c |
-
|
|
|
79af3c |
- class EtcdException(Exception):
|
|
|
79af3c |
- pass
|
|
|
79af3c |
-
|
|
|
79af3c |
- class EtcdNotFile(Exception):
|
|
|
79af3c |
- pass
|
|
|
79af3c |
-
|
|
|
79af3c |
- class EtcdKeyNotFound(Exception):
|
|
|
79af3c |
- pass
|
|
|
79af3c |
-
|
|
|
79af3c |
- class EtcdAlreadyExist(Exception):
|
|
|
79af3c |
- pass
|
|
|
79af3c |
-
|
|
|
79af3c |
-from custodia.plugin import CSStore, CSStoreError, CSStoreExists
|
|
|
79af3c |
-from custodia.plugin import PluginOption
|
|
|
79af3c |
-
|
|
|
79af3c |
-
|
|
|
79af3c |
-class EtcdStore(CSStore):
|
|
|
79af3c |
- etcd_server = PluginOption(str, '127.0.0.1', None)
|
|
|
79af3c |
- etcd_port = PluginOption(int, '4001', None)
|
|
|
79af3c |
- namespace = PluginOption(str, '/custodia', None)
|
|
|
79af3c |
-
|
|
|
79af3c |
- def __init__(self, config, section):
|
|
|
79af3c |
- super(EtcdStore, self).__init__(config, section)
|
|
|
79af3c |
- # Initialize the DB by trying to create the default table
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- self.etcd = Client(self.etcd_server, self.etcd_port)
|
|
|
79af3c |
- self.etcd.write(self.namespace, None, dir=True)
|
|
|
79af3c |
- except EtcdNotFile:
|
|
|
79af3c |
- # Already exists
|
|
|
79af3c |
- pass
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error creating namespace %s",
|
|
|
79af3c |
- self.namespace)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to init db')
|
|
|
79af3c |
-
|
|
|
79af3c |
- def _absolute_key(self, key):
|
|
|
79af3c |
- """Get absolute path to key and validate key"""
|
|
|
79af3c |
- if '//' in key:
|
|
|
79af3c |
- raise ValueError("Invalid empty components in key '%s'" % key)
|
|
|
79af3c |
- parts = key.split('/')
|
|
|
79af3c |
- if set(parts).intersection({'.', '..'}):
|
|
|
79af3c |
- raise ValueError("Invalid relative components in key '%s'" % key)
|
|
|
79af3c |
- return '/'.join([self.namespace] + parts).replace('//', '/')
|
|
|
79af3c |
-
|
|
|
79af3c |
- def get(self, key):
|
|
|
79af3c |
- self.logger.debug("Fetching key %s", key)
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- result = self.etcd.get(self._absolute_key(key))
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error fetching key %s", key)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to get key')
|
|
|
79af3c |
- self.logger.debug("Fetched key %s got result: %r", key, result)
|
|
|
79af3c |
- return result.value # pylint: disable=no-member
|
|
|
79af3c |
-
|
|
|
79af3c |
- def set(self, key, value, replace=False):
|
|
|
79af3c |
- self.logger.debug("Setting key %s to value %s (replace=%s)",
|
|
|
79af3c |
- key, value, replace)
|
|
|
79af3c |
- path = self._absolute_key(key)
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- self.etcd.write(path, value, prevExist=replace)
|
|
|
79af3c |
- except EtcdAlreadyExist as err:
|
|
|
79af3c |
- raise CSStoreExists(str(err))
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error storing key %s", key)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to store key')
|
|
|
79af3c |
-
|
|
|
79af3c |
- def span(self, key):
|
|
|
79af3c |
- path = self._absolute_key(key)
|
|
|
79af3c |
- self.logger.debug("Creating directory %s", path)
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- self.etcd.write(path, None, dir=True, prevExist=False)
|
|
|
79af3c |
- except EtcdAlreadyExist as err:
|
|
|
79af3c |
- raise CSStoreExists(str(err))
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error storing key %s", key)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to store key')
|
|
|
79af3c |
-
|
|
|
79af3c |
- def list(self, keyfilter='/'):
|
|
|
79af3c |
- path = self._absolute_key(keyfilter)
|
|
|
79af3c |
- if path != '/':
|
|
|
79af3c |
- path = path.rstrip('/')
|
|
|
79af3c |
- self.logger.debug("Listing keys matching %s", path)
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- result = self.etcd.read(path, recursive=True)
|
|
|
79af3c |
- except EtcdKeyNotFound:
|
|
|
79af3c |
- return None
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error listing %s", keyfilter)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to list keys')
|
|
|
79af3c |
- self.logger.debug("Searched for %s got result: %r", path, result)
|
|
|
79af3c |
- value = set()
|
|
|
79af3c |
- for entry in result.get_subtree():
|
|
|
79af3c |
- if entry.key == path:
|
|
|
79af3c |
- continue
|
|
|
79af3c |
- name = entry.key[len(path):]
|
|
|
79af3c |
- if entry.dir and not name.endswith('/'):
|
|
|
79af3c |
- name += '/'
|
|
|
79af3c |
- value.add(name.lstrip('/'))
|
|
|
79af3c |
- return sorted(value)
|
|
|
79af3c |
-
|
|
|
79af3c |
- def cut(self, key):
|
|
|
79af3c |
- self.logger.debug("Removing key %s", key)
|
|
|
79af3c |
- try:
|
|
|
79af3c |
- self.etcd.delete(self._absolute_key(key))
|
|
|
79af3c |
- except EtcdKeyNotFound:
|
|
|
79af3c |
- self.logger.debug("Key %s not found", key)
|
|
|
79af3c |
- return False
|
|
|
79af3c |
- except EtcdException:
|
|
|
79af3c |
- self.logger.exception("Error removing key %s", key)
|
|
|
79af3c |
- raise CSStoreError('Error occurred while trying to cut key')
|
|
|
79af3c |
- self.logger.debug("Key %s removed", key)
|
|
|
79af3c |
- return True
|
|
|
79af3c |
diff --git a/docs/source/plugins/stores.rst b/docs/source/plugins/stores.rst
|
|
|
79af3c |
index ed921ba..d715f31 100644
|
|
|
79af3c |
--- a/docs/source/plugins/stores.rst
|
|
|
79af3c |
+++ b/docs/source/plugins/stores.rst
|
|
|
79af3c |
@@ -5,7 +5,6 @@ Stores
|
|
|
79af3c |
:nosignatures:
|
|
|
79af3c |
|
|
|
79af3c |
custodia.store.sqlite.SqliteStore
|
|
|
79af3c |
- custodia.store.etcdstore.EtcdStore
|
|
|
79af3c |
custodia.store.encgen.EncryptedOverlay
|
|
|
79af3c |
|
|
|
79af3c |
.. autoclass:: custodia.store.sqlite.SqliteStore
|
|
|
79af3c |
@@ -13,11 +12,6 @@ Stores
|
|
|
79af3c |
:undoc-members:
|
|
|
79af3c |
:show-inheritance:
|
|
|
79af3c |
|
|
|
79af3c |
-.. autoclass:: custodia.store.etcdstore.EtcdStore
|
|
|
79af3c |
- :members:
|
|
|
79af3c |
- :undoc-members:
|
|
|
79af3c |
- :show-inheritance:
|
|
|
79af3c |
-
|
|
|
79af3c |
.. autoclass:: custodia.store.encgen.EncryptedOverlay
|
|
|
79af3c |
:members:
|
|
|
79af3c |
:undoc-members:
|
|
|
79af3c |
diff --git a/setup.py b/setup.py
|
|
|
79af3c |
index a7c398a..c8f270d 100755
|
|
|
79af3c |
--- a/setup.py
|
|
|
79af3c |
+++ b/setup.py
|
|
|
79af3c |
@@ -15,16 +15,12 @@ requirements = [
|
|
|
79af3c |
'requests'
|
|
|
79af3c |
]
|
|
|
79af3c |
|
|
|
79af3c |
-# extra requirements
|
|
|
79af3c |
-etcd_requires = ['python-etcd']
|
|
|
79af3c |
-
|
|
|
79af3c |
# test requirements
|
|
|
79af3c |
-test_requires = ['coverage', 'pytest'] + etcd_requires
|
|
|
79af3c |
+test_requires = ['coverage', 'pytest']
|
|
|
79af3c |
|
|
|
79af3c |
extras_require = {
|
|
|
79af3c |
- 'etcd_store': etcd_requires,
|
|
|
79af3c |
'test': test_requires,
|
|
|
79af3c |
- 'test_docs': ['docutils', 'markdown'] + etcd_requires,
|
|
|
79af3c |
+ 'test_docs': ['docutils', 'markdown'],
|
|
|
79af3c |
'test_pep8': ['flake8', 'flake8-import-order', 'pep8-naming'],
|
|
|
79af3c |
'test_pylint': ['pylint'] + test_requires,
|
|
|
79af3c |
}
|
|
|
79af3c |
@@ -70,7 +66,6 @@ custodia_consumers = [
|
|
|
79af3c |
custodia_stores = [
|
|
|
79af3c |
'EncryptedOverlay = custodia.store.encgen:EncryptedOverlay',
|
|
|
79af3c |
'EncryptedStore = custodia.store.enclite:EncryptedStore',
|
|
|
79af3c |
- 'EtcdStore = custodia.store.etcdstore:EtcdStore',
|
|
|
79af3c |
'SqliteStore = custodia.store.sqlite:SqliteStore',
|
|
|
79af3c |
]
|
|
|
79af3c |
|
|
|
79af3c |
--
|
|
|
79af3c |
2.9.3
|
|
|
79af3c |
|