summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-09-28 10:23:24 -0400
committerSimo Sorce <simo@redhat.com>2015-10-19 12:17:42 -0400
commit1d813cc53b9c03636967600f0e31e0cafb14813c (patch)
tree0f2ae59cdd510f17171e6fff568b4e01bcd2269b
parentbd2e62767e6287dcaf5275362338682fc555d4ce (diff)
downloadcustodia-1d813cc53b9c03636967600f0e31e0cafb14813c.tar.gz
custodia-1d813cc53b9c03636967600f0e31e0cafb14813c.tar.xz
custodia-1d813cc53b9c03636967600f0e31e0cafb14813c.zip
Extend store interface to create namespaces
Use a new verb, "span" to create namespaces/containers. This will be needed for the Etcd plugin which need to distinguish between a directory and a key. The sqlite/enclite just pass the request to their set() method. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Christian Heimes <cheimes@redhat.com>
-rw-r--r--custodia/secrets.py6
-rw-r--r--custodia/store/interface.py3
-rw-r--r--custodia/store/sqlite.py37
3 files changed, 43 insertions, 3 deletions
diff --git a/custodia/secrets.py b/custodia/secrets.py
index b2979d0..a009dcb 100644
--- a/custodia/secrets.py
+++ b/custodia/secrets.py
@@ -63,7 +63,7 @@ class Secrets(HTTPConsumer):
# create default namespace if it is the only missing piece
if len(trail) == 2 and default == trail[0]:
container = self._db_container_key(default, '')
- self.root.store.set(container, '')
+ self.root.store.span(container)
return True
return False
@@ -117,7 +117,7 @@ class Secrets(HTTPConsumer):
if not ok:
raise HTTPError(404)
- self.root.store.set(basename, '')
+ self.root.store.span(basename)
except CSStoreExists:
raise HTTPError(409)
except CSStoreError:
@@ -133,7 +133,7 @@ class Secrets(HTTPConsumer):
raise HTTPError(404)
if len(keylist) != 0:
raise HTTPError(409)
- ret = self.root.store.cut(basename)
+ ret = self.root.store.cut(basename.rstrip('/'))
except CSStoreError:
raise HTTPError(500)
diff --git a/custodia/store/interface.py b/custodia/store/interface.py
index 11c2e36..850fc91 100644
--- a/custodia/store/interface.py
+++ b/custodia/store/interface.py
@@ -23,6 +23,9 @@ class CSStore(object):
def set(self, key, value, replace=False):
raise NotImplementedError
+ def span(self, key):
+ raise NotImplementedError
+
def list(self, keyfilter=None):
raise NotImplementedError
diff --git a/custodia/store/sqlite.py b/custodia/store/sqlite.py
index 482787a..0a50651 100644
--- a/custodia/store/sqlite.py
+++ b/custodia/store/sqlite.py
@@ -57,6 +57,8 @@ class SqliteStore(CSStore):
cur.execute(create)
def set(self, key, value, replace=False):
+ if key.endswith('/'):
+ raise ValueError('Invalid Key name, cannot end in "/"')
if replace:
query = "INSERT OR REPLACE into %s VALUES (?, ?)"
else:
@@ -74,6 +76,22 @@ class SqliteStore(CSStore):
log_error("Error storing key %s: [%r]" % (key, repr(err)))
raise CSStoreError('Error occurred while trying to store key')
+ def span(self, key):
+ name = key.rstrip('/')
+ query = "INSERT into %s VALUES (?, '')"
+ setdata = query % (self.table,)
+ try:
+ conn = sqlite3.connect(self.dburi)
+ with conn:
+ c = conn.cursor()
+ self._create(c)
+ c.execute(setdata, (name,))
+ except sqlite3.IntegrityError as err:
+ raise CSStoreExists(str(err))
+ except sqlite3.Error as err:
+ log_error("Error creating key %s: [%r]" % (name, repr(err)))
+ raise CSStoreError('Error occurred while trying to span container')
+
def list(self, keyfilter=''):
path = keyfilter.rstrip('/')
child_prefix = path if path == '' else path + '/'
@@ -209,3 +227,22 @@ class SqliteStoreTests(unittest.TestCase):
def test_6_cut_2_empty(self):
ret = self.store.cut('keycut')
self.assertEqual(ret, False)
+
+ def test_7_span_1(self):
+ self.store.span('/span')
+ value = self.store.list('/span')
+ self.assertEqual(value, [])
+
+ def test_7_span_2(self):
+ self.store.span('/span/2')
+ self.store.span('/span/2/span')
+ value = self.store.list('/span')
+ self.assertEqual(value, ['2', '2/span'])
+ value = self.store.list('/span/2')
+ self.assertEqual(value, ['span'])
+ value = self.store.list('/span/2/span')
+ self.assertEqual(value, [])
+
+ def test_8_cut_span(self):
+ ret = self.store.cut('/span/2')
+ self.assertEqual(ret, True)