This repository was archived by the owner on Nov 19, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Allow specifying multiple Marathon addresses and failover to each sequentially #74
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
9bdd9eb
Allow specifying multiple Marathon addresses and failover...
JayH5 b11801f
Update Dockerfile and README for multiple Marathon addresses
JayH5 e2821fb
Log error when all Marathon endpoints failed
JayH5 a5b6aa8
Fix PerLocationAgent KeyError test on py2
JayH5 7b59dc3
Merge branch 'develop' into marathon-failover
JayH5 8667cdc
Restore some use of uri() to MarathonClient tests
JayH5 6e606ca
Fix merged service test
JayH5 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,39 @@ | ||
from treq.client import HTTPClient | ||
from twisted.internet.defer import fail | ||
from uritools import urisplit | ||
|
||
|
||
class FailingAgent(object): | ||
def __init__(self, error=RuntimeError()): | ||
self.error = error | ||
|
||
""" A twisted.web.iweb.IAgent that does nothing but fail. """ | ||
def request(self, method, uri, headers=None, bodyProducer=None): | ||
return fail(RuntimeError()) | ||
return fail(self.error) | ||
|
||
|
||
""" A Treq client that will fail with a RuntimeError for any request made. """ | ||
failing_client = HTTPClient(FailingAgent()) | ||
|
||
|
||
class PerLocationAgent(object): | ||
""" | ||
A twisted.web.iweb.IAgent that delegates to other agents for specific URI | ||
locations. | ||
""" | ||
def __init__(self): | ||
self.agents = {} | ||
|
||
def add_agent(self, location, agent): | ||
""" | ||
Add an agent for URIs with the specified location. | ||
:param bytes location: | ||
The URI authority/location (e.g. b'example.com:80') | ||
:param agent: The twisted.web.iweb.IAgent to use for the location | ||
""" | ||
self.agents[location] = agent | ||
|
||
def request(self, method, uri, headers=None, bodyProducer=None): | ||
agent = self.agents[urisplit(uri).authority] | ||
return agent.request( | ||
method, uri, headers=headers, bodyProducer=bodyProducer) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import pytest | ||
from testtools import ExpectedException | ||
from testtools.assertions import assert_that | ||
from testtools.matchers import ( | ||
Equals, Is, IsInstance, MatchesAll, MatchesDict, MatchesListwise, | ||
MatchesPredicate, MatchesStructure) | ||
from testtools.twistedsupport import failed, succeeded | ||
from twisted.internet.defer import succeed | ||
|
||
from marathon_acme.tests.helpers import FailingAgent, PerLocationAgent | ||
|
||
|
||
class DummyAgent(object): | ||
def request(self, *args, **kwargs): | ||
return succeed((args, kwargs)) | ||
|
||
|
||
class TestPerLocationAgent(object): | ||
@pytest.fixture | ||
def agent(self): | ||
return PerLocationAgent() | ||
|
||
def test_keyerror_if_location_unset(self, agent): | ||
""" | ||
When a request is made using the agent and no delegate agent has been | ||
added for the URI location/authority, a KeyError is expected. | ||
""" | ||
with ExpectedException(KeyError, r"b?'foo:8080'"): | ||
agent.request(b'GET', b'http://foo:8080') | ||
|
||
def test_delegates_to_agent_for_location(self, agent): | ||
""" | ||
When a request is made using the agent, the added agents are delegated | ||
to based on the URI location/authority. | ||
""" | ||
agent.add_agent(b'foo:8080', DummyAgent()) | ||
agent.add_agent(b'bar:8080', FailingAgent(RuntimeError('bar'))) | ||
agent.add_agent(b'foo:9090', FailingAgent(RuntimeError('9090'))) | ||
|
||
d = agent.request(b'GET', b'http://foo:8080') | ||
assert_that(d, succeeded(MatchesListwise([ | ||
MatchesListwise([Equals(b'GET'), Equals(b'http://foo:8080')]), | ||
MatchesDict({'headers': Is(None), 'bodyProducer': Is(None)}) | ||
]))) | ||
|
||
# Scheme doesn't matter | ||
d = agent.request(b'GET', b'https://foo:8080') | ||
assert_that(d, succeeded(MatchesListwise([ | ||
MatchesListwise([Equals(b'GET'), Equals(b'https://foo:8080')]), | ||
MatchesDict({'headers': Is(None), 'bodyProducer': Is(None)}) | ||
]))) | ||
|
||
# Path doesn't matter | ||
d = agent.request(b'GET', b'http://foo:8080/bar/baz') | ||
assert_that(d, succeeded(MatchesListwise([ | ||
MatchesListwise([ | ||
Equals(b'GET'), Equals(b'http://foo:8080/bar/baz')]), | ||
MatchesDict({'headers': Is(None), 'bodyProducer': Is(None)}) | ||
]))) | ||
|
||
# Hostname *does* matter | ||
d = agent.request(b'GET', b'http://bar:8080') | ||
assert_that(d, failed(MatchesStructure(value=MatchesAll( | ||
IsInstance(RuntimeError), | ||
MatchesPredicate(str, Equals('bar')) | ||
)))) | ||
|
||
# Port *does* matter | ||
d = agent.request(b'GET', b'http://foo:9090') | ||
assert_that(d, failed(MatchesStructure(value=MatchesAll( | ||
IsInstance(RuntimeError), | ||
MatchesPredicate(str, Equals('9090')) | ||
)))) | ||
|
||
# Other args passed through | ||
d = agent.request(b'GET', b'http://foo:8080', 'bar', 'baz') | ||
assert_that(d, succeeded(MatchesListwise([ | ||
MatchesListwise([Equals(b'GET'), Equals(b'http://foo:8080')]), | ||
MatchesDict( | ||
{'headers': Equals('bar'), 'bodyProducer': Equals('baz')}) | ||
]))) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of space-separated opts like
-m foo bar baz
, because it looks like the extras are positional args.Can we make these comma-separated or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I maybe do this in a separate PR and do it for
--lb
as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely.