Example #1
0
 def setUp(self):
     # Sets up the root user, toggles auth
     u = auth.EtcdUser(self.client, 'root')
     u.password = '******'
     u.write()
     self.client = etcd_gevent.Client(port=6001, username='******',
                                      password='******')
     self.unauth_client = etcd_gevent.Client(port=6001)
     a = auth.Auth(self.client)
     a.active = True
Example #2
0
 def test_allow_reconnect(self):
     """ Fails if allow_reconnect is false and a list of hosts is given"""
     with self.assertRaises(etcd_gevent.EtcdException):
         etcd_gevent.Client(host=(('localhost', 4001), ('localhost',
                                                        4002)), )
     # This doesn't raise an exception
     client = etcd_gevent.Client(
         host=(('localhost', 4001), ('localhost', 4002)),
         allow_reconnect=True,
         use_proxies=True,
     )
Example #3
0
 def test_discover(self):
     """Tests discovery."""
     answers = []
     for i in range(1, 3):
         r = mock.create_autospec(dns.rdtypes.IN.SRV.SRV)
         r.port = 2379
         try:
             method = dns.name.from_unicode
         except AttributeError:
             method = dns.name.from_text
         r.target = method(u'etcd{}.example.com'.format(i))
         answers.append(r)
     dns.resolver.query = mock.create_autospec(dns.resolver.query,
                                               return_value=answers)
     self.machines = etcd_gevent.Client.machines
     etcd_gevent.Client.machines = mock.create_autospec(
         etcd_gevent.Client.machines,
         return_value=[u'https://etcd2.example.com:2379'])
     c = etcd_gevent.Client(srv_domain="example.com",
                            allow_reconnect=True,
                            protocol="https")
     etcd_gevent.Client.machines = self.machines
     self.assertEquals(c.host, u'etcd1.example.com')
     self.assertEquals(c.port, 2379)
     self.assertEquals(c._machines_cache,
                       [u'https://etcd2.example.com:2379'])
Example #4
0
    def test_set(self):
        """ Can set a value """
        client = etcd_gevent.Client()
        client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
            201, '{"action":"SET",'
            '"node": {'
            '"key":"/testkey",'
            '"value":"test",'
            '"newKey":true,'
            '"expiration":"2013-09-14T00:56:59.316195568+02:00",'
            '"ttl":19,"modifiedIndex":183}}'))

        result = client.set('/testkey', 'test', ttl=19)

        self.assertEquals(
            etcd_gevent.EtcdResult(
                **{
                    u'action': u'SET',
                    'node': {
                        u'expiration': u'2013-09-14T00:56:59.316195568+02:00',
                        u'modifiedIndex': 183,
                        u'key': u'/testkey',
                        u'newKey': True,
                        u'ttl': 19,
                        u'value': u'test'
                    }
                }), result)
Example #5
0
 def test_put(self):
     """ http put request """
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(status=200, data='arbitrary json data')
     client.http.request = mock.Mock(return_value=response)
     result = client.api_execute('/v2/keys/testkey', client._MPUT)
     self.assertEquals('arbitrary json data'.encode('utf-8'), result.data)
Example #6
0
 def test_get_error_invalid(self):
     """ http get error request invalid """
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(status=400, data='{){){)*garbage*')
     client.http.request = mock.Mock(return_value=response)
     self.assertRaises(etcd_gevent.EtcdException, client.api_execute,
                       '/v2/keys/testkey', client._MGET)
Example #7
0
 def test_test_and_set(self):
     """ Can test and set a value """
     client = etcd_gevent.Client()
     client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
         200, '{"action":"SET",'
         '"node": {'
         '"key":"/testkey",'
         '"prevValue":"test",'
         '"value":"newvalue",'
         '"expiration":"2013-09-14T02:09:44.24390976+02:00",'
         '"ttl":49,"modifiedIndex":203}}'))
     result = client.test_and_set('/testkey', 'newvalue', 'test', ttl=19)
     self.assertEquals(
         etcd_gevent.EtcdResult(
             **{
                 u'action': u'SET',
                 u'node': {
                     u'expiration': u'2013-09-14T02:09:44.24390976+02:00',
                     u'modifiedIndex': 203,
                     u'key': u'/testkey',
                     u'prevValue': u'test',
                     u'ttl': 49,
                     u'value': u'newvalue'
                 }
             }), result)
Example #8
0
    def test_read(self):
        u = auth.EtcdUser(self.client, 'root')
        # Reading an existing user succeeds
        try:
            u.read()
        except Exception:
            self.fail("reading the root user raised an exception")

        # roles for said user are fetched
        self.assertEquals(u.roles, set(['root']))

        # The user is correctly rendered out
        self.assertEquals(u._to_net(), [{'user': '******', 'password': None,
                                         'roles': ['root']}])

        # An inexistent user raises the appropriate exception
        u = auth.EtcdUser(self.client, 'user.does.not.exist')
        self.assertRaises(etcd_gevent.EtcdKeyNotFound, u.read)

        # Reading with an unauthenticated client raises an exception
        u = auth.EtcdUser(self.unauth_client, 'root')
        self.assertRaises(etcd_gevent.EtcdInsufficientPermissions, u.read)

        # Generic errors are caught
        c = etcd_gevent.Client(port=9999)
        u = auth.EtcdUser(c, 'root')
        self.assertRaises(etcd_gevent.EtcdException, u.read)
Example #9
0
 def test_index_watch(self):
     """ Can watch values from index """
     client = etcd_gevent.Client()
     client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
         200, '{"action":"SET",'
         '"node": {'
         '"key":"/testkey",'
         '"value":"test",'
         '"newKey":true,'
         '"expiration":"2013-09-14T01:35:07.623681365+02:00",'
         '"ttl":19,'
         '"modifiedIndex":180}}'))
     result = client.watch('/testkey', index=180)
     self.assertEquals(
         etcd_gevent.EtcdResult(
             **{
                 u'action': u'SET',
                 u'node': {
                     u'expiration': u'2013-09-14T01:35:07.623681365+02:00',
                     u'modifiedIndex': 180,
                     u'key': u'/testkey',
                     u'newKey': True,
                     u'ttl': 19,
                     u'value': u'test'
                 }
             }), result)
Example #10
0
 def test_reconnect_not_allowed(self):
     """ INTEGRATION: fail on server kill if not allow_reconnect """
     self.processHelper.stop()
     self.processHelper.run(number=3)
     self.client = etcd_gevent.Client(port=6001, allow_reconnect=False)
     self.processHelper.kill_one(0)
     self.assertRaises(etcd_gevent.EtcdConnectionFailed, self.client.get,
                       '/test_set')
Example #11
0
    def test_get_set_unauthenticated(self):
        """ INTEGRATION: set/get a new value unauthenticated (http->https) """

        client = etcd_gevent.Client(port=6001)

        # See above for the reason of this change
        self.assertRaises(etcd_gevent.EtcdException, client.set, '/test_set',
                          'test-key')
        self.assertRaises(etcd_gevent.EtcdException, client.get, '/test_set')
Example #12
0
    def test_get_set_authenticated(self):
        """ INTEGRATION: set/get a new value authenticated """

        client = etcd_gevent.Client(port=6001,
                                    protocol='https',
                                    ca_cert=self.ca_cert_path)

        set_result = client.set('/test_set', 'test-key')
        get_result = client.get('/test_set')
Example #13
0
    def test_get_set_unauthenticated_with_ca(self):
        """ INTEGRATION: try unauthenticated with validation (https->https)"""
        client = etcd_gevent.Client(protocol='https',
                                    port=6001,
                                    ca_cert=self.ca2_cert_path)

        self.assertRaises(etcd_gevent.EtcdConnectionFailed, client.set,
                          '/test-set', 'test-key')
        self.assertRaises(etcd_gevent.EtcdConnectionFailed, client.get,
                          '/test-set')
Example #14
0
 def setUpClass(cls):
     program = cls._get_exe()
     cls.directory = tempfile.mkdtemp(prefix='etcd-gevent')
     cls.processHelper = helpers.EtcdProcessHelper(
         cls.directory,
         proc_name=program,
         port_range_start=6001,
         internal_port_range_start=8001)
     cls.processHelper.run(number=cls.cl_size)
     cls.client = etcd_gevent.Client(port=6001)
Example #15
0
 def test_get_error_request_invalid(self):
     """ http get error request invalid """
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(status=400, data='{)*garbage')
     client.http.request = mock.Mock(return_value=response)
     try:
         client.api_execute('/v2/keys/testkey', client._MGET)
         self.fail()
     except etcd_gevent.EtcdException as e:
         self.assertEqual(str(e), "Bad response : {)*garbage")
Example #16
0
    def test_in(self):
        """ Can check if key is in client """
        client = etcd_gevent.Client()
        client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
            200, '{"action":"GET",'
            '"node": {'
            '"key":"/testkey",'
            '"value":"test",'
            '"modifiedIndex":190}}'))
        result = '/testkey' in client

        self.assertEquals(True, result)
Example #17
0
    def test_get_set_unauthenticated(self):
        """ INTEGRATION: set/get a new value unauthenticated (http->https) """

        client = etcd_gevent.Client(port=6001)

        # Since python 3 raises a MaxRetryError here, this gets caught in
        # different code blocks in python 2 and python 3, thus messages are
        # different. Python 3 does the right thing(TM), for the record
        self.assertRaises(etcd_gevent.EtcdException, client.set, '/test_set',
                          'test-key')

        self.assertRaises(etcd_gevent.EtcdException, client.get, '/test_set')
Example #18
0
    def test_write_and_delete(self):
        # Create an user
        u = auth.EtcdUser(self.client, 'test_user')
        u.roles.add('guest')
        u.roles.add('root')
        # directly from my suitcase
        u.password = '******'
        try:
            u.write()
        except:
            self.fail("creating a user doesn't work")
        # Password gets wiped
        self.assertEquals(u.password, None)
        u.read()
        # Verify we can log in as this user and access the auth (it has the
        # root role)
        cl = etcd_gevent.Client(port=6001, username='******',
                                password='******')
        ul = auth.EtcdUser(cl, 'root')
        try:
            ul.read()
        except etcd_gevent.EtcdInsufficientPermissions:
            self.fail("Reading auth with the new user is not possible")

        self.assertEquals(u.name, "test_user")
        self.assertEquals(u.roles, set(['guest', 'root']))
        # set roles as a list, it works!
        u.roles = ['guest', 'test_group']
        # We need this or the new API will return an internal error
        r = auth.EtcdRole(self.client, 'test_group')
        r.acls = {'*': 'R', '/test/*': 'RW'}
        r.write()
        try:
            u.write()
        except:
            self.fail("updating a user you previously created fails")
        u.read()
        self.assertIn('test_group', u.roles)

        # Unauthorized access is properly handled
        ua = auth.EtcdUser(self.unauth_client, 'test_user')
        self.assertRaises(etcd_gevent.EtcdInsufficientPermissions, ua.write)

        # now let's test deletion
        du = auth.EtcdUser(self.client, 'user.does.not.exist')
        self.assertRaises(etcd_gevent.EtcdKeyNotFound, du.delete)

        # Delete test_user
        u.delete()
        self.assertRaises(etcd_gevent.EtcdKeyNotFound, u.read)
        # Permissions are properly handled
        self.assertRaises(etcd_gevent.EtcdInsufficientPermissions, ua.delete)
Example #19
0
 def test_get_error(self):
     """ http get error request 101"""
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(status=400,
                                 data='{"message": "message",'
                                 ' "cause": "cause",'
                                 ' "errorCode": 100}')
     client.http.request = mock.Mock(return_value=response)
     try:
         client.api_execute('/v2/keys/testkey', client._MGET)
         assert False
     except etcd_gevent.EtcdKeyNotFound as e:
         self.assertEquals(str(e), 'message : cause')
Example #20
0
 def test_set_not_file_error(self):
     """ http post error request 102 """
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(
         status=400,
         data='{"message": "message", "cause": "cause", "errorCode": 102}')
     client.http.request = mock.Mock(return_value=response)
     payload = {'value': 'value', 'prevValue': 'oldValue', 'ttl': '60'}
     try:
         client.api_execute('/v2/keys/testkey', client._MPUT, payload)
         self.fail()
     except etcd_gevent.EtcdNotFile as e:
         self.assertEquals('message : cause', str(e))
Example #21
0
 def test_get_error_unknown(self):
     """ http get error request unknown """
     client = etcd_gevent.Client()
     response = FakeHTTPResponse(status=400,
                                 data='{"message": "message",'
                                 ' "cause": "cause",'
                                 ' "errorCode": 42}')
     client.http.request = mock.Mock(return_value=response)
     try:
         client.api_execute('/v2/keys/testkey', client._MGET)
         self.fail()
     except etcd_gevent.EtcdException as e:
         self.assertEqual(str(e), "message : cause")
Example #22
0
    def test_reconnect(self):
        """ INTEGRATION: get key after the server we're connected fails. """
        self.processHelper.stop()
        self.processHelper.run(number=3)
        self.client = etcd_gevent.Client(port=6001, allow_reconnect=True)
        set_result = self.client.set('/test_set', 'test-key1')
        get_result = self.client.get('/test_set')

        self.assertEquals('test-key1', get_result.value)

        self.processHelper.kill_one(0)

        get_result = self.client.get('/test_set')
        self.assertEquals('test-key1', get_result.value)
Example #23
0
    def test_use_proxies(self, mocker):
        """Do not overwrite the machines cache when using proxies"""
        mocker.return_value = ['https://10.0.0.2:4001',
                               'https://10.0.0.3:4001',
                               'https://10.0.0.4:4001']
        c = etcd_gevent.Client(
            host=(('localhost', 4001), ('localproxy', 4001)),
            protocol='https',
            allow_reconnect=True,
            use_proxies=True
        )

        self.assertEquals(c._machines_cache, ['https://localproxy:4001'])
        self.assertEquals(c._base_uri, 'https://localhost:4001')
        self.assertNotIn(c.base_uri, c._machines_cache)

        c = etcd_gevent.Client(
            host=(('localhost', 4001), ('10.0.0.2', 4001)),
            protocol='https',
            allow_reconnect=True,
            use_proxies=False
        )
        self.assertIn('https://10.0.0.3:4001', c._machines_cache)
        self.assertNotIn(c.base_uri, c._machines_cache)
Example #24
0
    def test_reconnet_fails(self):
        """ INTEGRATION: fails to reconnect if no available machines """
        self.processHelper.stop()
        # Start with three instances (0, 1, 2)
        self.processHelper.run(number=3)
        # Connect to instance 0
        self.client = etcd_gevent.Client(port=6001, allow_reconnect=True)
        set_result = self.client.set('/test_set', 'test-key1')

        get_result = self.client.get('/test_set')
        self.assertEquals('test-key1', get_result.value)
        self.processHelper.kill_one(2)
        self.processHelper.kill_one(1)
        self.processHelper.kill_one(0)
        self.assertRaises(etcd_gevent.EtcdException, self.client.get, '/test_set')
Example #25
0
 def test_eternal_watch(self):
     """ Can watch values from generator """
     client = etcd_gevent.Client()
     client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
         200, '{"action":"SET",'
         '"node": {'
         '"key":"/testkey",'
         '"value":"test",'
         '"newKey":true,'
         '"expiration":"2013-09-14T01:35:07.623681365+02:00",'
         '"ttl":19,'
         '"modifiedIndex":180}}'))
     for result in range(1, 5):
         result = next(client.eternal_watch('/testkey', index=180))
         yield self.check_watch, result
Example #26
0
    def test_test_and_test_failure(self):
        """ Exception will be raised if prevValue != value in test_set """

        client = etcd_gevent.Client()
        client.api_execute = mock.Mock(side_effect=ValueError(
            'The given PrevValue is not equal'
            ' to the value of the key : TestAndSet: 1!=3'))
        try:
            result = client.test_and_set('/testkey',
                                         'newvalue',
                                         'test',
                                         ttl=19)
        except ValueError as e:
            #from ipdb import set_trace; set_trace()
            self.assertEquals(
                'The given PrevValue is not equal'
                ' to the value of the key : TestAndSet: 1!=3', str(e))
Example #27
0
    def test_reconnect_with_several_hosts_passed(self):
        """ INTEGRATION: receive several hosts at connection setup. """
        self.processHelper.stop()
        self.processHelper.run(number=3)
        self.client = etcd_gevent.Client(
            host=(
                ('127.0.0.1', 6004),
                ('127.0.0.1', 6001)),
            allow_reconnect=True)
        set_result = self.client.set('/test_set', 'test-key1')
        get_result = self.client.get('/test_set')

        self.assertEquals('test-key1', get_result.value)

        self.processHelper.kill_one(0)

        get_result = self.client.get('/test_set')
        self.assertEquals('test-key1', get_result.value)
Example #28
0
    def test_get_set_authenticated(self):
        """ INTEGRATION: connecting to server with mutual auth """
        # This gives an unexplicable ssl error, as connecting to the same
        # Etcd cluster where this fails with the exact same code this
        # doesn't fail

        client = etcd_gevent.Client(port=6001,
                                    protocol='https',
                                    cert=self.client_all_cert,
                                    ca_cert=self.ca_cert_path)

        set_result = client.set('/test_set', 'test-key')
        self.assertEquals(u'set', set_result.action.lower())
        self.assertEquals(u'/test_set', set_result.key)
        self.assertEquals(u'test-key', set_result.value)
        get_result = client.get('/test_set')
        self.assertEquals('get', get_result.action.lower())
        self.assertEquals('/test_set', get_result.key)
        self.assertEquals('test-key', get_result.value)
Example #29
0
    def test_get(self):
        """ Can get a value """
        client = etcd_gevent.Client()
        client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
            200, '{"action":"GET",'
            '"node": {'
            '"key":"/testkey",'
            '"value":"test",'
            '"modifiedIndex":190}}'))

        result = client.get('/testkey')
        self.assertEquals(
            etcd_gevent.EtcdResult(
                **{
                    u'action': u'GET',
                    u'node': {
                        u'modifiedIndex': 190,
                        u'key': u'/testkey',
                        u'value': u'test'
                    }
                }), result)
Example #30
0
 def test_delete(self):
     """ Can delete a value """
     client = etcd_gevent.Client()
     client.api_execute = mock.Mock(return_value=FakeHTTPResponse(
         200, '{"action":"DELETE",'
         '"node": {'
         '"key":"/testkey",'
         '"prevValue":"test",'
         '"expiration":"2013-09-14T01:06:35.5242587+02:00",'
         '"modifiedIndex":189}}'))
     result = client.delete('/testkey')
     self.assertEquals(
         etcd_gevent.EtcdResult(
             **{
                 u'action': u'DELETE',
                 u'node': {
                     u'expiration': u'2013-09-14T01:06:35.5242587+02:00',
                     u'modifiedIndex': 189,
                     u'key': u'/testkey',
                     u'prevValue': u'test'
                 }
             }), result)