Skip to content

Commit c95e9d1

Browse files
committed
Merge pull request #72 from Marchowes/MarchDSFImprovements
March dsf improvements
2 parents 388d29b + 73090a1 commit c95e9d1

File tree

3 files changed

+148
-7
lines changed

3 files changed

+148
-7
lines changed

HISTORY.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
Release History
22
---------------
33

4+
1.6.2 (2016-3-7)
5+
++++++++++++++++
6+
*Added order_rulesets() to TrafficDirector object, for re-ordering Rulesets
7+
*Added index=n to Ruleset create() so New rulesets can be placed in a certain location in the chain.
8+
*Added getters for single DSF objects get_record(), get_record_set() etc.
9+
*Fixed bug with DSF Monitor options
10+
*Fixed bug where adding criteria to rulesets with 'always' criteria_type changes it to 'geoip' by default.
11+
12+
13+
414
1.6.1 (2016-2-11)
15+
+++++++++++++++++
516
*Added UNKNOWN record type
617
*DSF records status getter added
718

dyn/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
Requires Python 2.6 or higher, or the "simplejson" package.
77
"""
8-
version_info = (1, 6, 1)
8+
version_info = (1, 6, 2)
99
__name__ = 'dyn'
1010
__doc__ = 'A python wrapper for the DynDNS and DynEmail APIs'
1111
__author__ = 'Jonathan Nappi, Cole Tuininga, Marc Howes'

dyn/tm/services/dsf.py

Lines changed: 136 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
__all__ = ['get_all_dsf_services', 'get_all_record_sets','get_all_failover_chains',
1616
'get_all_response_pools', 'get_all_rulesets', 'get_all_dsf_monitors',
1717
'get_all_records', 'get_all_notifiers', 'DSFARecord', 'DSFSSHFPRecord',
18+
'get_record', 'get_record_set', 'get_failover_chain', 'get_response_pool',
19+
'get_ruleset', 'get_dsf_monitor',
1820
'DSFNotifier',
1921
'DSFAAAARecord', 'DSFALIASRecord', 'DSFCERTRecord', 'DSFCNAMERecord',
2022
'DSFDHCIDRecord', 'DSFDNAMERecord', 'DSFDNSKEYRecord', 'DSFDSRecord',
@@ -126,6 +128,101 @@ def get_all_dsf_monitors():
126128
mons.append(DSFMonitor(api=False, **dsf))
127129
return mons
128130

131+
def get_record(record_id, service, always_list = False):
132+
"""
133+
returns :class:`DSFRecord`
134+
:param record_id: id of record you wish to pull up
135+
:param service: id of service which this record belongs. Can either be
136+
the service_id or a :class:`TrafficDirector` Object
137+
:param always_list: Force the returned record to always be in a list.
138+
:return returns single record, unless this is a special record type, then a list is returned
139+
"""
140+
if service:
141+
_service_id = _checkType(service)
142+
143+
uri = '/DSFRecord/{}/{}'.format(_service_id, record_id)
144+
api_args = {'detail': 'Y'}
145+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
146+
record= _constructor(response['data'])
147+
if len(record) > 1 or always_list:
148+
return record
149+
else:
150+
return record[0]
151+
152+
def get_record_set(record_set_id, service):
153+
"""
154+
returns :class:`DSFRecordSet`
155+
:param record_set_id: id of record set you wish to pull up
156+
:param service: id of service which this record belongs. Can either be
157+
the service_id or a :class:`TrafficDirector` Object
158+
:return returns :class:`DSFRecordSet` Object
159+
"""
160+
if service:
161+
_service_id = _checkType(service)
162+
163+
uri = '/DSFRecordSet/{}/{}'.format(_service_id, record_set_id)
164+
api_args = {'detail': 'Y'}
165+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
166+
return DSFRecordSet(response['data'].pop('rdata_class'), api=False, **response['data'])
167+
168+
def get_failover_chain(failover_chain_id, service):
169+
"""
170+
returns :class:`DSFFailoverChain`
171+
:param failover_chain_id: id of :class:`DSFFailoverChain` you wish to pull up
172+
:param service: id of service which this record belongs. Can either be
173+
the service_id or a :class:`TrafficDirector` Object
174+
:return returns :class:`DSFFailoverChain` Object
175+
"""
176+
if service:
177+
_service_id = _checkType(service)
178+
179+
uri = '/DSFRecordSetFailoverChain/{}/{}'.format(_service_id, failover_chain_id)
180+
api_args = {'detail': 'Y'}
181+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
182+
return DSFFailoverChain(response['data'].pop('label'), api=False, **response['data'])
183+
184+
def get_response_pool(response_pool_id, service):
185+
"""
186+
returns :class:`DSFResponsePool`
187+
:param response_pool_id: id of :class:`DSFResponsePool` you wish to pull up
188+
:param service: id of service which this record belongs. Can either be
189+
the service_id or a :class:`TrafficDirector` Object
190+
:return returns :class:`DSFResponsePool` Object
191+
"""
192+
if service:
193+
_service_id = _checkType(service)
194+
195+
uri = '/DSFResponsePool/{}/{}'.format(_service_id, response_pool_id)
196+
api_args = {'detail': 'Y'}
197+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
198+
return DSFResponsePool(response['data'].pop('label'), api=False, **response['data'])
199+
200+
def get_ruleset(ruleset_id, service):
201+
"""
202+
returns :class:`DSFRuleset`
203+
:param ruleset_id: id of :class:`DSFRuleset` you wish to pull up
204+
:param service: id of service which this record belongs. Can either be
205+
the service_id or a :class:`TrafficDirector` Object
206+
:return returns :class:`DSFRuleset` Object
207+
"""
208+
if service:
209+
_service_id = _checkType(service)
210+
211+
uri = '/DSFRuleset/{}/{}'.format(_service_id, ruleset_id)
212+
api_args = {'detail': 'Y'}
213+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
214+
return DSFRuleset(response['data'].pop('label'), api=False, **response['data'])
215+
216+
def get_dsf_monitor(monitor_id):
217+
""" A quick :class:`DSFmonitor` getter, for consistency sake.
218+
:param monitor_id: id of :class:`DSFmonitor` you wish to pull up
219+
:return returns :class:`DSFmonitor` Object"""
220+
uri = '/DSFMonitor/{}'.format(monitor_id)
221+
api_args = {'detail': 'Y'}
222+
response = DynectSession.get_session().execute(uri, 'GET', api_args)
223+
return DSFMonitor(api=False, **response['data'])
224+
225+
129226
def _checkType(service):
130227
if isinstance(service, TrafficDirector):
131228
_service_id = service.service_id
@@ -2306,6 +2403,7 @@ def __init__(self, label, criteria_type, response_pools, criteria=None, failover
23062403
self._criteria_type = criteria_type
23072404
self._criteria = criteria
23082405
self._failover = failover
2406+
self._ordering = None
23092407
self._implicitPublish=True
23102408
if isinstance(response_pools, list) and len(response_pools) > 0 and \
23112409
isinstance(response_pools[0], dict):
@@ -2335,6 +2433,8 @@ def _post(self, dsf_id, publish=True):
23352433
api_args = {'publish': 'Y', 'label': self._label,
23362434
'criteria_type': self._criteria_type,
23372435
'criteria': self._criteria}
2436+
if self._ordering is not None:
2437+
api_args['ordering'] = self._ordering
23382438
if self._response_pools:
23392439
api_args['response_pools'] = [pool.to_json(skip_svc=True) for pool in self.response_pools]
23402440

@@ -2422,7 +2522,6 @@ def add_response_pool(self, response_pool, index=0, publish=True):
24222522
api_args['response_pools'].append({'dsf_response_pool_id': _response_pool_id})
24232523
self._update(api_args, publish)
24242524

2425-
24262525
def remove_response_pool(self, response_pool, publish=True):
24272526
"""
24282527
Removes passed in :class:`DSFResponsePool` from this :class:`DSFRuleSet`.
@@ -2487,15 +2586,18 @@ def order_response_pools(self, pool_list, publish=True):
24872586
self._update(api_args, publish)
24882587

24892588

2490-
def create(self, service, publish=True):
2589+
def create(self, service, index = None, publish=True):
24912590
"""Adds this :class:`DSFRuleset` to the passed in :class:`TrafficDirector`
24922591
:param service: a :class:`TrafficDirector` or id string for the :class:`TrafficDirector`
24932592
you wish to add this :class:`DSFRuleset` to.
2593+
:param index: in what position to serve this ruleset. 0 = first.
24942594
:param publish: publish at execution time. Default = True
24952595
"""
24962596
if self._dsf_ruleset_id:
24972597
raise Exception('Rule Set Already Exists. ID: {}'.format(self._dsf_ruleset_id))
24982598
_service_id = _checkType(service)
2599+
if index is not None:
2600+
self._ordering = index
24992601
self._post(_service_id, publish)
25002602

25012603

@@ -2543,7 +2645,14 @@ def criteria(self):
25432645
return self._criteria
25442646
@criteria.setter
25452647
def criteria(self, value):
2546-
api_args = {'criteria': value}
2648+
api_args = dict()
2649+
if type(value) is dict:
2650+
if value.get('geoip'):
2651+
for key, val in value['geoip'].items():
2652+
if len(val) != 0:
2653+
api_args['criteria_type'] = 'geoip'
2654+
2655+
api_args['criteria'] = value
25472656
self._update(api_args)
25482657
if self._implicitPublish:
25492658
self._criteria = value
@@ -2803,9 +2912,6 @@ def _build(self, data):
28032912
ep = DSFMonitorEndpoint(**endpoint)
28042913
ep._monitor = self
28052914
self._endpoints.append(ep)
2806-
elif key == 'options':
2807-
for opt_key, opt_val in val.items():
2808-
setattr(self, '_' + opt_key, opt_val)
28092915
elif key == 'active':
28102916
self._active = Active(val)
28112917
else:
@@ -3345,6 +3451,30 @@ def rulesets(self, value):
33453451
self._rulesets = value
33463452
self._rulesets.uri = self.uri
33473453

3454+
def order_rulesets(self, ruleset_list, publish=True):
3455+
"""
3456+
For reordering the ruleset list. simply pass in a ``list`` of :class:`DSFRulesets`s in the order
3457+
you wish them to be served.
3458+
:param ruleset_list: ordered ``list`` of :class:`DSFRulesets`
3459+
:param publish: Publish on execution. default = True
3460+
"""
3461+
3462+
if not isinstance(ruleset_list, list):
3463+
raise Exception('You must pass in an ordered list of response pool objects, or ids.')
3464+
_ruleset_list = list()
3465+
3466+
for list_item in ruleset_list:
3467+
if isinstance(list_item, DSFRuleset):
3468+
_ruleset_list.append(list_item._dsf_ruleset_id)
3469+
elif type(list_item) is str or type(list_item) is unicode:
3470+
_ruleset_list.append(list_item)
3471+
api_args = dict()
3472+
api_args['rulesets'] = list()
3473+
for ruleset_id in _ruleset_list:
3474+
api_args['rulesets'].append({'dsf_ruleset_id': ruleset_id})
3475+
self._update(api_args, publish)
3476+
3477+
33483478
@property
33493479
def nodeObjects(self):
33503480
"""A list of :class:`Node` Objects that are linked

0 commit comments

Comments
 (0)