Browse Source

WIP monitors management

pull/433/head
Ross McFarland 6 years ago
parent
commit
f6c60b69b7
No known key found for this signature in database GPG Key ID: 61C10C4FC8FE4A89
1 changed files with 103 additions and 7 deletions
  1. +103
    -7
      octodns/provider/ns1.py

+ 103
- 7
octodns/provider/ns1.py View File

@ -32,6 +32,7 @@ class Ns1Client(object):
client = NS1(apiKey=api_key)
self._records = client.records()
self._zones = client.zones()
self._monitors = client.monitors()
def _try(self, method, *args, **kwargs):
tries = self.retry_count
@ -66,6 +67,17 @@ class Ns1Client(object):
def records_delete(self, zone, domain, _type):
return self._try(self._records.delete, zone, domain, _type)
def monitors_list(self):
return self._try(self._monitors.list)
def monitors_create(self, **params):
body = {} # TODO: not clear what this is supposed to be
return self._try(self._monitors.create, body, **params)
def monitors_update(self, job_id, **params):
body = {} # TODO: not clear what this is supposed to be
return self._try(self._monitors.update, job_id, body, **params)
class Ns1Provider(BaseProvider):
'''
@ -136,9 +148,10 @@ class Ns1Provider(BaseProvider):
def _parse_notes(self, note):
data = {}
for piece in note.split(' '):
k, v = piece.split(':', 1)
data[k] = v
if note:
for piece in note.split(' '):
k, v = piece.split(':', 1)
data[k] = v
return data
def _data_for_geo_A(self, _type, record):
@ -258,7 +271,7 @@ class Ns1Provider(BaseProvider):
'_order': notes['rule-order'],
}
if geos:
rule['geos'] = geos
rule['geos'] = sorted(geos)
rules.append(rule)
# Order and convert to a list
@ -449,6 +462,79 @@ class Ns1Provider(BaseProvider):
len(zone.records) - before, exists)
return exists
def _extra_changes(self, desired, changes, **kwargs):
# TODO: check monitors to see if they need updated
return []
def _monitors_for(self, record):
# TODO: should this just be a global cache by fqdn, type, and value?
expected_host = record.fqdn[:-1]
expected_type = record._type
monitors = {}
# TODO: cache here or in Ns1Client
for monitor in self._client.monitors_list():
data = self._parse_notes(monitor['notes'])
if expected_host == data['host'] or \
expected_type == data['type']:
# This monitor does not belong to this record
config = monitor['config']
value = config['host']
monitors[value] = monitor
return monitors
def _sync_monitor(self, record, value, existing):
host = record.fqdn[:-1]
_type = record._type
request = 'GET {path} HTTP/1.0\\r\\nHost: {host}\\r\\n' \
'User-agent: NS1\\r\\n\\r\\n'.format(path=record.healthcheck_path,
host=host)
expected = {
'active': True,
'config': {
'connect_timeout': 2000,
'host': value,
'port': record.healthcheck_port,
'response_timeout': 10000,
'send': request,
'ssl': record.healthcheck_protocol == 'HTTPS',
},
'frequency': 60,
'job_type': 'tcp',
'name': '{} - {} - {}'.format(host, _type, value),
'notes': self._encode_notes({
'host': host,
'type': _type,
}),
'policy': 'quorum',
'rapid_recheck': False,
'region_scope': 'fixed',
# TODO: what should we do here dal, sjc, lga, sin, ams
'regions': ['lga'],
'rules': [{
'comparison': 'contains',
'key': 'output',
'value': '200 OK',
}],
}
if existing:
monitor_id = existing['id']
# See if the monitor needs updating
for k, v in expected.items():
if existing.get(k, '--missing--') != v:
self._client.monitors_update(monitor_id, **expected)
break
else:
return self._client.monitors_create(**expected)['id']
# TODO: this needs to return the feed
return None
def _params_for_A(self, record):
params = {'ttl': record.ttl}
@ -498,13 +584,21 @@ class Ns1Provider(BaseProvider):
'meta': meta,
}
# Build a list of primary values for each pool
existing_monitors = self._monitors_for(record)
# Build a list of primary values for each pool, including their
# monitor
pool_answers = defaultdict(list)
for pool_name, pool in sorted(pools.items()):
for value in pool.data['values']:
weight = value['weight']
value = value['value']
existing = existing_monitors.get(value)
monitor_id = self._sync_monitor(record, value, existing)
pool_answers[pool_name].append({
'answer': [value['value']],
'weight': value['weight'],
'answer': [value],
'weight': weight,
'monitor_id': monitor_id,
})
default_answers = [{
@ -531,6 +625,7 @@ class Ns1Provider(BaseProvider):
}),
'weight': answer['weight'],
},
'up': True, # TODO: this should be a monitor/feed
'region': pool_name, # the one we're answering
}
answers.append(answer)
@ -547,6 +642,7 @@ class Ns1Provider(BaseProvider):
'note': self._encode_notes({
'from': '--default--',
}),
'up': True,
'weight': 1,
},
'region': pool_name, # the one we're answering


Loading…
Cancel
Save