Skip to content

Commit

Permalink
Add support of Fastly directors (#27)
Browse files Browse the repository at this point in the history
* Add support of Fastly directors

* Add directors documentation to the README

* Revert VCLSNIPPET.type validation as its not part of director change
  • Loading branch information
cono authored and fstehle committed Aug 28, 2017
1 parent caef1a2 commit 799186b
Show file tree
Hide file tree
Showing 5 changed files with 381 additions and 1 deletion.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ $ ansible-galaxy install Jimdo.fastly
| backends | true | List of backends to service requests from your domains | |
| cache_settings | false | List of cache settings | |
| conditions | false | List of conditions | |
| directors | false | List of directors | |
| gzips | false | List of gzip configurations | |
| headers | false | List of headers to manipulate for each request | |
| response_objects | false | List of response objects | |
Expand Down Expand Up @@ -66,6 +67,21 @@ $ ansible-galaxy install Jimdo.fastly
| statement | true | string | |
| type | true | enum ('REQUEST', 'PREFETCH', 'CACHE', 'RESPONSE') | |

### Director

[Fastly documentation](https://docs.fastly.com/api/config#director)

| Field | Required | Type | Default |
|:----------|:---------|:--------------------------------------------------------|:--------|
| name | true | string | |
| backends | false | array of strings | |
| capacity | false | integer | 100 |
| comment | false | string | '' |
| quorum | false | integer | 75 |
| shield | false | string | |
| type | false | integer | 1 |
| retries | false | integer | 5 |

### Header

[Fastly documentation](https://docs.fastly.com/api/config#header)
Expand Down
62 changes: 61 additions & 1 deletion library/fastly_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
required: false
description:
- List of conditions
directors:
required: false
description:
- List of directors
gzips:
required: false
description:
Expand Down Expand Up @@ -195,6 +199,11 @@ def read_config(self, config, validate_choices, param_name):
raise FastlyValidationError(self.__class__.__name__,
"Field '%s' with value '%s' couldn't be converted to boolean" % (
param_name, value))
elif param_type == 'list':
if not isinstance(value, list):
raise FastlyValidationError(self.__class__.__name__,
"Field '%s' with value '%s' is not a list" % (
param_name, value))

if exclude_empty_str and value == "":
value = None
Expand Down Expand Up @@ -276,6 +285,30 @@ def __init__(self, config, validate_choices):
self.type = self.read_config(config, validate_choices, 'type')


class FastlyDirector(FastlyObject):
schema = {
'name': dict(required=True, type='str', default=None),
'backends': dict(required=False, type='list', default=None),
'capacity': dict(required=False, type='int', default=100),
'comment': dict(required=False, type='str', default=''),
'quorum': dict(required=False, type='int', default=75),
'shield': dict(required=False, type='str', default=None),
'type': dict(required=False, type='int', default=1),
'retries': dict(required=False, type='int', default=5)
}
sort_key = lambda f: f.name

def __init__(self, config, validate_choices):
self.name = self.read_config(config, validate_choices, 'name')
self.backends = self.read_config(config, validate_choices, 'backends')
self.capacity = self.read_config(config, validate_choices, 'capacity')
self.comment = self.read_config(config, validate_choices, 'comment')
self.quorum = self.read_config(config, validate_choices, 'quorum')
self.shield = self.read_config(config, validate_choices, 'shield')
self.type = self.read_config(config, validate_choices, 'type')
self.retries = self.read_config(config, validate_choices, 'retries')


class FastlyGzip(FastlyObject):
schema = {
'name': dict(required=True, type='str', default=None),
Expand Down Expand Up @@ -380,6 +413,7 @@ def __init__(self, configuration, validate_choices = True):
self.backends = []
self.cache_settings = []
self.conditions = []
self.directors = []
self.gzips = []
self.headers = []
self.response_objects = []
Expand All @@ -402,6 +436,10 @@ def __init__(self, configuration, validate_choices = True):
for condition in configuration['conditions']:
self.conditions.append(FastlyCondition(condition, validate_choices))

if 'directors' in configuration and configuration['directors'] is not None:
for director in configuration['directors']:
self.directors.append(FastlyDirector(director, validate_choices))

if 'gzips' in configuration and configuration['gzips'] is not None:
for gzip in configuration['gzips']:
self.gzips.append(FastlyGzip(gzip, validate_choices))
Expand All @@ -426,6 +464,7 @@ def __eq__(self, other):
and sorted(self.backends, key=FastlyBackend.sort_key) == sorted(other.backends, key=FastlyBackend.sort_key) \
and sorted(self.cache_settings, key=FastlyCacheSettings.sort_key) == sorted(other.cache_settings, key=FastlyCacheSettings.sort_key) \
and sorted(self.conditions, key=FastlyCondition.sort_key) == sorted(other.conditions, key=FastlyCondition.sort_key) \
and sorted(self.directors, key=FastlyDirector.sort_key) == sorted(other.directors, key=FastlyDirector.sort_key) \
and sorted(self.gzips, key=FastlyGzip.sort_key) == sorted(other.gzips, key=FastlyGzip.sort_key) \
and sorted(self.headers, key=FastlyHeader.sort_key) == sorted(other.headers, key=FastlyHeader.sort_key) \
and sorted(self.response_objects, key=FastlyResponseObject.sort_key) == sorted(other.response_objects, key=FastlyResponseObject.sort_key) \
Expand Down Expand Up @@ -503,7 +542,7 @@ def create_service(self, service_name):
if response.status == 200:
return self.get_service(response.payload['id'])
else:
raise Exception("Error creating service with name '%s'" % service_name)
raise Exception("Error creating service with name '%s': %s" % (service_name, response.payload['detail']))

def delete_service(self, service_name, deactivate_active_version=True):
service = self.get_service_by_name(service_name)
Expand Down Expand Up @@ -558,6 +597,21 @@ def create_backend(self, service_id, version, backend):
raise Exception("Error creating backend for for service %s, version %s (%s)" % (
service_id, version, response.payload['detail']))

def create_director(self, service_id, version, director):
response = self._request('/service/%s/version/%s/director' % (service_id, version), 'POST', director)
if response.status != 200:
raise Exception("Error creating director for service %s, version %s (%s)" % (
service_id, version, response.payload['detail']))

payload = response.payload
if director.backends is not None:
for backend in director.backends:
response = self._request('/service/%s/version/%s/director/%s/backend/%s' % (service_id, version, director.name, backend), 'POST')
if response.status != 200:
raise Exception("Error establishing a relationship between director %s and backend %s, service %s, version %s (%s)" % (
director.name, backend, service_id, version, response.payload['detail']))
return payload

def create_cache_settings(self, service_id, version, cache_settings):
response = self._request('/service/%s/version/%s/cache_settings' % (service_id, version), 'POST', cache_settings)
if response.status == 200:
Expand Down Expand Up @@ -669,6 +723,10 @@ def deploy_version_with_configuration(self, service_id, configuration, activate_
for backend in configuration.backends:
self.client.create_backend(service_id, version_number, backend)

# director should follow after backends
for director in configuration.directors:
self.client.create_director(service_id, version_number, director)

for cache_settings in configuration.cache_settings:
self.client.create_cache_settings(service_id, version_number, cache_settings)

Expand Down Expand Up @@ -718,6 +776,7 @@ def __init__(self):
backends=dict(default=None, required=True, type='list'),
cache_settings=dict(default=None, required=False, type='list'),
conditions=dict(default=None, required=False, type='list'),
directors=dict(default=None, required=False, type='list'),
gzips=dict(default=None, required=False, type='list'),
headers=dict(default=None, required=False, type='list'),
response_objects=dict(default=None, required=False, type='list'),
Expand All @@ -743,6 +802,7 @@ def configuration(self):
'backends': self.module.params['backends'],
'cache_settings': self.module.params['cache_settings'],
'conditions': self.module.params['conditions'],
'directors': self.module.params['directors'],
'gzips': self.module.params['gzips'],
'headers': self.module.params['headers'],
'response_objects': self.module.params['response_objects'],
Expand Down
Loading

0 comments on commit 799186b

Please sign in to comment.