]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
Configuration support for Google Cloud Storage backend.
authorItamar Turner-Trauring <itamar@futurefoundries.com>
Tue, 5 Mar 2013 16:38:40 +0000 (11:38 -0500)
committerDaira Hopwood <daira@jacaranda.org>
Fri, 17 Apr 2015 21:31:39 +0000 (22:31 +0100)
src/allmydata/storage/backends/cloud/cloud_backend.py
src/allmydata/storage/backends/cloud/googlestorage/googlestorage_container.py
src/allmydata/test/test_client.py

index 3d92525fbebea2376c03ab92c1e0eaaa7a7af5b3..14dee7498b48e07c8dcd5c77da9a7df5a438f435 100644 (file)
@@ -20,7 +20,7 @@ from allmydata.storage.backends.cloud.cloud_common import get_share_key, delete_
 from allmydata.mutable.layout import MUTABLE_MAGIC
 
 
-CLOUD_INTERFACES = ("cloud.s3", "cloud.openstack")
+CLOUD_INTERFACES = ("cloud.s3", "cloud.openstack", "cloud.googlestorage")
 
 
 def get_cloud_share(container, storage_index, shnum, total_size):
index 75264e239c7857a140c94eb5521f822f88c00087..af3a82a9437acf314962d8fccc14b94d300545e5 100644 (file)
@@ -26,12 +26,6 @@ from allmydata.storage.backends.cloud.cloud_common import IContainer, \
      ContainerItem, ContainerListing, CommonContainerMixin
 
 
-def configure_googlestorage_container(*args):
-    """
-    Configure the Google Cloud Storage container.
-    """
-
-
 class AuthenticationClient(object):
     """
     Retrieve access tokens for the Google Storage API, using OAuth 2.0.
@@ -227,19 +221,16 @@ class GoogleStorageContainer(CommonContainerMixin):
         return d
 
 
-if __name__ == '__main__':
-    from twisted.internet import reactor
-    from twisted.web.client import getPage
-    import sys
-    auth = AuthenticationClient(sys.argv[1], file(sys.argv[2]).read())
-    def println(result):
-        print result
-        reactor.stop()
-    def gotAuth(value):
-        return getPage("https://storage.googleapis.com/",
-                       headers={"Authorization": value,
-                                "x-goog-api-version": "2",
-                                "x-goog-project-id": sys.argv[3]}).addCallback(println)
-    auth.get_authorization_header().addCallback(gotAuth)
-    reactor.run()
-
+def configure_googlestorage_container(storedir, config):
+    """
+    Configure the Google Cloud Storage container.
+    """
+    account_email = config.get_config("storage", "googlestorage.account_email")
+    private_key = config.get_private_config("googlestorage_private_key")
+    bucket_name = config.get_config("storage", "googlestorage.bucket_name")
+    # Only necessary if we do bucket creation/deletion, otherwise can be
+    # removed:
+    project_id = config.get_config("storage", "googlestorage.project_id")
+
+    authclient = AuthenticationClient(account_email, private_key)
+    return GoogleStorageContainer(authclient, project_id, bucket_name)
index 0888a0b6c4ad37a2c84010f1c2ccf9fa33879089..bb7a086afa59df646b5c5c32f3a87eed0dde5e59 100644 (file)
@@ -430,6 +430,74 @@ class Basic(testutil.ReallyEqualMixin, unittest.TestCase):
                                     "openstack.container = test\n")
         self.failUnlessRaises(MissingConfigEntry, client.Client, basedir)
 
+    def test_googlestorage_config_required(self):
+        """
+        account_email, bucket_name and project_id are all required by
+        googlestorage configuration.
+        """
+        configs = ["googlestorage.account_email = u@example.com",
+                   "googlestorage.bucket_name = bucket",
+                   "googlestorage.project_id = 456"]
+        for i in range(len(configs)):
+            basedir = self.mktemp()
+            os.mkdir(basedir)
+            bad_config = configs[:]
+            del bad_config[i]
+            self._write_secret(basedir, "googlestorage_private_key")
+            fileutil.write(os.path.join(basedir, "tahoe.cfg"),
+                           BASECONFIG +
+                           "[storage]\n" +
+                           "enabled = true\n" +
+                           "backend = cloud.googlestorage\n" +
+                           "\n".join(bad_config) + "\n")
+            self.failUnlessRaises(MissingConfigEntry, client.Client, basedir)
+
+    def test_googlestorage_config_required_private_key(self):
+        """
+        googlestorage_private_key secret is required by googlestorage
+        configuration.
+        """
+        basedir = self.mktemp()
+        os.mkdir(basedir)
+        fileutil.write(os.path.join(basedir, "tahoe.cfg"),
+                       BASECONFIG +
+                       "[storage]\n" +
+                       "enabled = true\n" +
+                       "backend = cloud.googlestorage\n" +
+                       "googlestorage.account_email = u@example.com\n" +
+                       "googlestorage.bucket_name = bucket\n" +
+                       "googlestorage.project_id = 456\n")
+        self.failUnlessRaises(MissingConfigEntry, client.Client, basedir)
+
+    @mock.patch('allmydata.storage.backends.cloud.googlestorage.googlestorage_container.AuthenticationClient')
+    @mock.patch('allmydata.storage.backends.cloud.googlestorage.googlestorage_container.GoogleStorageContainer')
+    def test_googlestorage_config(self, mock_OpenStackContainer, mock_AuthenticationClient):
+        """
+        Given good configuration, we correctly configure a good GoogleStorageContainer.
+        """
+        basedir = self.mktemp()
+        os.mkdir(basedir)
+        self._write_secret(basedir, "googlestorage_private_key", "sekrit")
+        fileutil.write(os.path.join(basedir, "tahoe.cfg"),
+                       BASECONFIG +
+                       "[storage]\n" +
+                       "enabled = true\n" +
+                       "backend = cloud.googlestorage\n" +
+                       "googlestorage.account_email = u@example.com\n" +
+                       "googlestorage.bucket_name = bucket\n" +
+                       "googlestorage.project_id = 456\n")
+        c = client.Client(basedir)
+        server = c.getServiceNamed("storage")
+        self.failUnless(isinstance(server.backend, CloudBackend), server.backend)
+        # Protect against typos with isinstance(), because mock is dangerous.
+        self.assertFalse(isinstance(mock_AuthenticationClient.assert_called_once_with,
+                                    mock.Mock))
+        mock_AuthenticationClient.assert_called_once_with("u@example.com", "sekrit")
+        self.assertFalse(isinstance(mock_OpenStackContainer.assert_called_once_with,
+                                    mock.Mock))
+        mock_OpenStackContainer.assert_called_once_with(mock_AuthenticationClient.return_value,
+                                                        "456", "bucket")
+
     def test_expire_mutable_false_unsupported(self):
         basedir = "client.Basic.test_expire_mutable_false_unsupported"
         os.mkdir(basedir)