Skip to content

Commit

Permalink
skip auth header tests for etcd<v3.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Revolution1 committed Dec 24, 2018
1 parent ba91ce4 commit 8c0f087
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 42 deletions.
8 changes: 5 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ env:

before_install:
- docker pull quay.io/coreos/etcd:$ETCD_VER
- docker run -d -p 2379:2379 -p 2380:2380 --name etcd3_1 quay.io/coreos/etcd:$ETCD_VER etcd --name node1 --initial-advertise-peer-urls http://0.0.0.0:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://0.0.0.0:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster node1=http://0.0.0.0:2380
- docker ps
- sudo docker cp etcd3_1:/usr/local/bin/etcdctl /usr/bin/etcdctl
# - docker run -d -p 2379:2379 -p 2380:2380 --name etcd3_1 quay.io/coreos/etcd:$ETCD_VER etcd --name node1 --initial-advertise-peer-urls http://0.0.0.0:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://0.0.0.0:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster node1=http://0.0.0.0:2380
# - docker ps
- docker create --name tmp quay.io/coreos/etcd:$ETCD_VER
- docker cp tmp:/usr/local/bin/etcdctl /usr/bin/etcdctl
- docker rm tmp
- which etcdctl

# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
Expand Down
4 changes: 2 additions & 2 deletions etcd3/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""

import json

import requests
import six
from six.moves import urllib_parse
Expand Down Expand Up @@ -189,7 +188,8 @@ def call_rpc(self, method, data=None, stream=False, encode=True, raw=False, **kw
if self.token:
kwargs.setdefault('headers', {}).setdefault('authorization', self.token)
kwargs.setdefault('headers', {}).setdefault('user_agent', self.user_agent)
kwargs.setdefault('headers', {}).update(self.headers)
for k, v in self.headers.items():
kwargs.setdefault('headers', {}).setdefault(k, v)
if isinstance(data, dict):
if encode:
data = self._encodeRPCRequest(method, data)
Expand Down
14 changes: 9 additions & 5 deletions etcd3/stateful/watch.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import time

import logging
import re
import six
import socket
import threading
import time
from collections import deque

import six
from requests import ConnectionError
from requests.exceptions import ChunkedEncodingError

Expand Down Expand Up @@ -110,6 +110,7 @@ def __init__(self, client, max_retries=-1, key=None, range_end=None, start_revis
"""
self.client = client
self.revision = None
self.watch_id = None
self.retries = 0
self.errors = deque(maxlen=20)
if max_retries == -1:
Expand Down Expand Up @@ -163,9 +164,10 @@ def request_create(self):

def request_cancel(self): # pragma: no cover
"""
Cancel the watcher [Not Implemented because of etcd3]
Cancel the watcher [Not Implemented because of etcd3 returns no watch_id]
"""
pass
if self.watch_id:
return self.client.watch_cancel(watch_id=self.watch_id)

def get_filter(self, filter):
"""
Expand Down Expand Up @@ -301,6 +303,7 @@ def stop(self):
if not self._resp or (self._resp and self._resp.raw.closed):
return
try:
self.request_cancel()
s = socket.fromfd(self._resp.raw._fp.fileno(), socket.AF_INET, socket.SOCK_STREAM)
s.shutdown(socket.SHUT_RDWR)
s.close()
Expand Down Expand Up @@ -368,6 +371,7 @@ def __iter__(self):
if 'created' in r:
log.debug("watch request created")
self.start_revision = r.header.revision
self.watch_id = r.watch_id
if 'events' in r:
for event in r.events:
yield Event(event)
Expand Down
10 changes: 8 additions & 2 deletions tests/envs.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import logging
import os

from six.moves.urllib_parse import urlparse

logging.basicConfig(format='%(name)s %(levelname)s - %(message)s')
log = logging.getLogger()
log.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
log.addHandler(handler)

ETCD_ENDPOINT = os.getenv('ETCD_ENDPOINT') or 'http://localhost:2379'
_url = urlparse(ETCD_ENDPOINT)

protocol = _url.scheme

host, port = _url.netloc.split(':')

ETCD_VER = os.getenv('ETCD_VER') or 'v3.3'
ETCD_VER = os.getenv('ETCD_VER') or 'v3.3.0'

ETCD_IMG = 'quay.io/coreos/etcd:' + ETCD_VER
50 changes: 28 additions & 22 deletions tests/test_auth_apis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import pytest
import re

from etcd3.client import Client
from etcd3.errors import ErrAuthNotEnabled
Expand All @@ -8,7 +10,7 @@
from etcd3.models import authpbPermissionType
from etcd3.utils import incr_last_byte
from tests.docker_cli import docker_run_etcd_main
from .envs import protocol, host
from .envs import protocol, host, ETCD_VER
from .etcd_go_cli import etcdctl, NO_ETCD_SERVICE


Expand Down Expand Up @@ -43,9 +45,10 @@ def enable_auth(): # pragma: no cover


@pytest.mark.skipif(NO_ETCD_SERVICE, reason="no etcd service available")
# @pytest.mark.skipif(re.match(r'v3\.[0-2]\.{0,1}', ETCD_VER), reason="etcd < v3.3.0 does not support auth header")
def test_auth_flow(client, request):
teardown_auth(client)
request.addfinalizer(lambda:teardown_auth(client))
request.addfinalizer(lambda: teardown_auth(client))

# test error
with pytest.raises(ErrRootUserNotExist):
Expand Down Expand Up @@ -82,26 +85,29 @@ def test_auth_flow(client, request):
assert len(r.roles) == 1
assert r.roles[0] == 'root'

# test auth enable
client.auth_enable()
r = client.authenticate('root', 'root')
assert r.token

# test client auth
client.auth('root', 'root')
assert client.token
assert client.user_get('root')

# test user change password
client.user_change_password('root', 'changed')
client.auth('root', 'changed')
client.user_change_password('root', 'root')
client.auth('root', 'root')

# test auth disable
client.auth_disable()
with pytest.raises(ErrAuthNotEnabled):
client.authenticate('root', 'root')
if re.match(r'v3\.[0-2]\.{0,1}', ETCD_VER):
logging.info('skipping tests of apis with auth enabled, cause etcd < v3.3.0 does not support auth header')
else:
# test auth enable
client.auth_enable()
r = client.authenticate('root', 'root')
assert r.token

# test client auth
client.auth('root', 'root')
assert client.token
assert client.user_get('root')

# test user change password
client.user_change_password('root', 'changed')
client.auth('root', 'changed')
client.user_change_password('root', 'root')
client.auth('root', 'root')

# test auth disable
client.auth_disable()
with pytest.raises(ErrAuthNotEnabled):
client.authenticate('root', 'root')

# test user revoke role
client.user_revoke_role('root', 'root')
Expand Down
18 changes: 13 additions & 5 deletions tests/test_py3/test_aio_auth_apis.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import asyncio

import logging
import pytest
import re

from etcd3 import AioClient
from ..envs import protocol, host, port
from tests.docker_cli import docker_run_etcd_main
from ..envs import protocol, host, ETCD_VER
from ..etcd_go_cli import NO_ETCD_SERVICE
from ..etcd_go_cli import etcdctl

Expand All @@ -24,8 +27,8 @@ async def aio_client(event_loop, request):
"""
init Etcd3Client, close its connection-pool when teardown
"""

c = AioClient(host, port, protocol)
_, p, _ = docker_run_etcd_main()
c = AioClient(host, p, protocol)

def teardown():
async def _t():
Expand All @@ -37,6 +40,7 @@ async def _t():
request.addfinalizer(teardown)
return c


def teardown_auth(): # pragma: no cover
"""
disable auth, delete all users and roles
Expand All @@ -55,14 +59,18 @@ def enable_auth(): # pragma: no cover
etcdctl('user grant root root')
etcdctl('auth enable')


@pytest.mark.skipif(NO_ETCD_SERVICE, reason="no etcd service available")
@pytest.mark.asyncio
async def test_async_client_auth(aio_client, request):
teardown_auth()
enable_auth()
request.addfinalizer(teardown_auth)

# test client auth
await aio_client.auth('root', 'root')
assert aio_client.token
assert aio_client.user_get('root')

if re.match(r'v3\.[0-2]\.{0,1}', ETCD_VER):
logging.info('skipping tests of apis with auth enabled, cause etcd < v3.3.0 does not support auth header')
else:
assert await aio_client.user_get('root')
8 changes: 5 additions & 3 deletions tests/test_py3/test_aio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import pytest

from etcd3 import AioClient
from ..docker_cli import docker_rm_etcd_ssl, docker_run_etcd_ssl, CERT_PATH, KEY_PATH, CA_PATH, NO_DOCKER_SERVICE
from ..envs import protocol, host, port
from ..docker_cli import docker_rm_etcd_ssl, docker_run_etcd_ssl, CERT_PATH, KEY_PATH, CA_PATH, NO_DOCKER_SERVICE, \
docker_run_etcd_main
from ..envs import protocol, host
from ..etcd_go_cli import NO_ETCD_SERVICE
from ..etcd_go_cli import etcdctl

Expand All @@ -27,7 +28,8 @@ async def aio_client(event_loop, request):
init Etcd3Client, close its connection-pool when teardown
"""

c = AioClient(host, port, protocol)
_, p, _ = docker_run_etcd_main()
c = AioClient(host, p, protocol)

def teardown():
async def _t():
Expand Down

0 comments on commit 8c0f087

Please sign in to comment.