コード例 #1
0
def import_zone_data(filename, api_key, **kwargs):
    nsone_obj = NSONE(apiKey=api_key)
    extension = os.path.splitext(filename)[1]

    with open(filename, 'rb') as f:
        if extension == '.csv':
            reader = csv.DictReader(f)
            data = transform_csv(reader)
        elif extension == '.json':
            data = transform_json(json.loads(f))

    if kwargs.get('delete'):
        delete_zone_data(nsone_obj, data)
        return

    for k, v in data.iteritems():

        try:
            zone = nsone_obj.createZone(k)
            print 'Added Zone {}'.format(zone)
        except AuthException as e:
            # Invalid api key passed in
            print e.message
            return
        except ResourceException as e:
            # zone already exists
            print '{} {}'.format(k, e.message)
            zone = nsone_obj.loadZone(k)

        for rec in v:

            answers = rec['Data'].split()
            try:
                # determine which record type to add using types provided in the file
                method_name = 'add_{}'.format(rec['Type'])
                add_method = getattr(zone, method_name)
                # data corresponds to the answer and it might have priority values
                record = add_method(k, [answers], ttl=rec['TTL'])
                print 'Successfully Added record {}'.format(record)
            except ResourceException as e:
                # record already exists, so add answers to it
                # Or Invalid add method
                print '{} {}'.format(rec, e.message)
                try:
                    record = nsone_obj.loadRecord(k, rec['Type'], k)
                    print 'Successfully loaded record {}'.format(k, rec['Type'])
                    recordAnswers = {answer['answer'][0] for answer in record.data['answers']}
                    if recordAnswers.intersection(answers[0]):
                        record.addAnswers(answers)
                        print 'Added answer: {}'.format(answers[0])
                    record.addAnswers([answers])
                    print 'Successfully Processed Answers {}'.format(answers)
                except ResourceException as e:
                    # Invalid format for answer, so ignore this answer, or invalid record type
                    print e.message
                    continue
コード例 #2
0
def main():
        nsone = NSONE(apiKey='NSONE_API_KEY_GOES_HERE')
        zonenames = get_zones(nsone)
        for i in range(0, len(zonenames)):
            qps = get_qps(nsone, zonenames[i])
            #print(zonenames[i] + ': ' + str(qps))
            dd_send(zonenames[i], qps)
コード例 #3
0
    def __init__(self, apiKey, data, delete):
        """
        Args:
            apiKey (str):  The Nsone Api Key
            data (Dict):  Zone Data Dict
            delete (bool): Delete Flag, defaults to false from argument parser
        """

        self.config.createFromAPIKey(apiKey)
        self.config['transport'] = 'twisted'
        self.nsoneObj = NSONE(config=self.config)
        self.data = data
        self.deleteData = delete
コード例 #4
0
ファイル: cli.py プロジェクト: vfrazao-ns1/ns1-cli
    def load_rest_client(self):
        """Loads ns1 rest client config"""
        opts = self.rest_cfg_opts

        # Create default config without any key
        cfg = Config()
        cfg.createFromAPIKey('')

        if opts.get('path', None):
            cfg.loadFromFile(opts['path'])
        elif opts.get('api_key'):
            cfg.createFromAPIKey(opts['api_key'])
        else:
            path = os.path.join(self.home_dir, self.DEFAULT_CONFIG_FILE)
            if os.path.exists(path):
                cfg.loadFromFile(path)

        if opts.get('api_key_id'):
            cfg.useKeyId(opts['api_key_id'])

        if opts.get('endpoint'):
            cfg['endpoint'] = opts['endpoint']

        if opts.get('transport'):
            cfg['transport'] = opts['transport']

        if opts.get('ignore_ssl'):
            cfg['ignore-ssl-errors'] = opts['ignore_ssl']

        if cfg['ignore-ssl-errors']:
            import requests
            from requests.packages.urllib3.exceptions import InsecureRequestWarning
            requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

        # Store the cli cfg dict as an attr of the rest config instance.
        for k, v in self.cfg.items():
            cfg['cli'][k] = v

        self.rest = NSONE(config=cfg)
コード例 #5
0
ファイル: zones.py プロジェクト: amirwollman/nsone-python
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

######################
# LOAD / CREATE ZONE #
######################

# to load an existing zone, get a Zone object back
test_zone = nsone.loadZone('test.com')

# or create a new zone, get a Zone object back
# you can specify options like retry, refresh, expiry, nx_ttl, etc
zone = nsone.createZone('example.com', nx_ttl=3600)
print(zone)

# once you have a Zone, you can access all the zone information via the
# data property
コード例 #6
0
ファイル: ns1.py プロジェクト: sgerrand/octodns
class Ns1Provider(BaseProvider):
    '''
    Ns1 provider

    nsone:
        class: octodns.provider.ns1.Ns1Provider
        api_key: env/NS1_API_KEY
    '''
    SUPPORTS_GEO = False
    ZONE_NOT_FOUND_MESSAGE = 'server error: zone not found'

    def __init__(self, id, api_key, *args, **kwargs):
        self.log = getLogger('Ns1Provider[{}]'.format(id))
        self.log.debug('__init__: id=%s, api_key=***', id)
        super(Ns1Provider, self).__init__(id, *args, **kwargs)
        self._client = NSONE(apiKey=api_key)

    def _data_for_A(self, _type, record):
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': record['short_answers'],
        }

    _data_for_AAAA = _data_for_A
    _data_for_SPF = _data_for_A
    _data_for_TXT = _data_for_A

    def _data_for_CNAME(self, _type, record):
        return {
            'ttl': record['ttl'],
            'type': _type,
            'value': record['short_answers'][0],
        }

    _data_for_PTR = _data_for_CNAME

    def _data_for_MX(self, _type, record):
        values = []
        for answer in record['short_answers']:
            priority, value = answer.split(' ', 1)
            values.append({
                'priority': priority,
                'value': value,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NAPTR(self, _type, record):
        values = []
        for answer in record['short_answers']:
            order, preference, flags, service, regexp, replacement = \
                answer.split(' ', 5)
            values.append({
                'flags': flags,
                'order': order,
                'preference': preference,
                'regexp': regexp,
                'replacement': replacement,
                'service': service,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NS(self, _type, record):
        return {
            'ttl':
            record['ttl'],
            'type':
            _type,
            'values': [
                a if a.endswith('.') else '{}.'.format(a)
                for a in record['short_answers']
            ],
        }

    def _data_for_SRV(self, _type, record):
        values = []
        for answer in record['short_answers']:
            priority, weight, port, target = answer.split(' ', 3)
            values.append({
                'priority': priority,
                'weight': weight,
                'port': port,
                'target': target,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def populate(self, zone, target=False):
        self.log.debug('populate: name=%s', zone.name)

        try:
            nsone_zone = self._client.loadZone(zone.name[:-1])
            records = nsone_zone.data['records']
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            records = []

        before = len(zone.records)
        for record in records:
            _type = record['type']
            data_for = getattr(self, '_data_for_{}'.format(_type))
            name = zone.hostname_from_fqdn(record['domain'])
            record = Record.new(zone, name, data_for(_type, record))
            zone.add_record(record)

        self.log.info('populate:   found %s records',
                      len(zone.records) - before)

    def _params_for_A(self, record):
        return {'answers': record.values, 'ttl': record.ttl}

    _params_for_AAAA = _params_for_A
    _params_for_NS = _params_for_A
    _params_for_SPF = _params_for_A
    _params_for_TXT = _params_for_A

    def _params_for_CNAME(self, record):
        return {'answers': [record.value], 'ttl': record.ttl}

    _params_for_PTR = _params_for_CNAME

    def _params_for_MX(self, record):
        values = [(v.priority, v.value) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_NAPTR(self, record):
        values = [(v.order, v.preference, v.flags, v.service, v.regexp,
                   v.replacement) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_SRV(self, record):
        values = [(v.priority, v.weight, v.port, v.target)
                  for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _get_name(self, record):
        return record.fqdn[:-1] if record.name == '' else record.name

    def _apply_Create(self, nsone_zone, change):
        new = change.new
        name = self._get_name(new)
        _type = new._type
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        getattr(nsone_zone, 'add_{}'.format(_type))(name, **params)

    def _apply_Update(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        new = change.new
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        record.update(**params)

    def _apply_Delete(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        record.delete()

    def _apply(self, plan):
        desired = plan.desired
        changes = plan.changes
        self.log.debug('_apply: zone=%s, len(changes)=%d', desired.name,
                       len(changes))

        domain_name = desired.name[:-1]
        try:
            nsone_zone = self._client.loadZone(domain_name)
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            self.log.debug('_apply:   no matching zone, creating')
            nsone_zone = self._client.createZone(domain_name)

        for change in changes:
            class_name = change.__class__.__name__
            getattr(self, '_apply_{}'.format(class_name))(nsone_zone, change)
コード例 #7
0
# TWISTED #
###########

from nsone import NSONE, Config
from twisted.internet import defer, reactor

config = Config()
# load default config
config.loadFromFile(Config.DEFAULT_CONFIG_FILE)
# to load directly from apikey instead, use
# config.createFromAPIKey('qACMD09OJXBxT7XOuRs8')

# override default synchronous transport. note, this would normally go
# in config file.
config['transport'] = 'twisted'
nsone = NSONE(config=config)


@defer.inlineCallbacks
def getQPS():
    # when twisted transport is in use, all of the NSONE methods return
    # Deferred. yield them to gather the results, or add callbacks/errbacks
    # to be run when results are available
    zone = yield nsone.loadZone('test.com')
    qps = yield zone.qps()
    defer.returnValue(qps)


def gotQPS(result):
    print("current QPS for test.com: %s" % result['qps'])
    reactor.stop()
コード例 #8
0
ファイル: zones.py プロジェクト: tomprince/nsone-python
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

######################
# LOAD / CREATE ZONE #
######################

# to load an existing zone, get a Zone object back
test_zone = nsone.loadZone('test.com')

# or create a new zone, get a Zone object back
# you can specify options like retry, refresh, expiry, nx_ttl, etc
zone = nsone.createZone('example.com', nx_ttl=3600)
print(zone)

# once you have a Zone, you can access all the zone information via the
# data property
コード例 #9
0
class NsoneImporter(object):
    """
    Attributes:
        config (nsone.Config): The configuration for the nsone requests.
        nsoneObj (nsone.NSONE): Instance of the nsone object used for http requests
        data (dict): Dictionary containing the zone data used by all methods for importing
        deleteData (bool): Attribute used to call deletion endpoints instead of importing
    """

    config = Config()


    def __init__(self, apiKey, data, delete):
        """
        Args:
            apiKey (str):  The Nsone Api Key
            data (Dict):  Zone Data Dict
            delete (bool): Delete Flag, defaults to false from argument parser
        """

        self.config.createFromAPIKey(apiKey)
        self.config['transport'] = 'twisted'
        self.nsoneObj = NSONE(config=self.config)
        self.data = data
        self.deleteData = delete


    def _deleteZoneData(self):
        """
        Parent method that triggers callback chain for deleting all zones.

        Makes call to deleteZonesandRecords method and depending on the response,
        the success or error callbacks are fired.

        Each call to deleteZonesandRecords is an instance of a deferred object and
        each object is collected for graceful termination
        """

        dl = []
        for zoneName, records in self.data:
            deleteZoneRes = self._deleteZonesAndRecords(zoneName, records, self.nsoneObj)
            deleteZoneRes.addCallback(self._deleteZoneSuccess, zoneName)
            deleteZoneRes.addErrback(self._deleteZoneFailure, zoneName)
            dl.append(deleteZoneRes)
        return defer.DeferredList(dl, fireOnOneErrback=True)


    @defer.inlineCallbacks
    def _deleteZonesAndRecords(self, zoneName, records, nsoneObj):
        """
        Returns a deferred object that calls the delete method of the nsone object.

        Args:
            zoneName (str):  The zone name from the data dictionary
            records (Dict):  a list of records belonging to this zone
            nsoneObj (nsone.NSONE): Instance of the nsone object

        """

        zone = yield nsoneObj.loadZone(zoneName)
        yield zone.delete()


    def _deleteZoneSuccess(self, response, zoneName):
        """
        Success callback for deleteZonesAndRecords deferred object.
        Triggered if there are no errors when calling the api

        Args:
            response (None): Upon success, the delete method returns None
            zoneName (str):  The zone name
        """

        print 'Successfully Deleted Zone: {}'.format(zoneName)


    def _deleteZoneFailure(self, failure, zoneName):
        """
        Error callback for deleteZonesAndRecords deferred object.
        Triggered if there are errors when calling the api

        Args:
            failure (twisted.python.failure)
            zoneName (str):  The zone name
        """

        print '{}: {}'.format(zoneName, failure.getErrorMessage())


    def _importZoneData(self):
        """
        The parent method that triggers all of the callback chains for importing zone data.

        Loops through all of the zone data and creates a deferred object for every
        zone and adds Success and Error callbacks for each deferred instance.

        Tracks all of the deferreds by appending them to a deferred list.
        If no errors occur, the success callback is triggered. If even a single
        error occurs, the fireOnOneErrback parameter is set to true and
        the error callback is triggered and the program exits.

        NOTE: Auth exceptions are not explicitely checked since if an
        nsone.rest.errors.AuthException is raised, the deferred list error back
        will fire and the program will exit

        Returns:
            defer.DeferredList


        """
        dl = []
        for zoneName, records in self.data:
            zone = self._createZone(zoneName)
            zone.addCallback(self._createZoneSuccess, zoneName, records, self.nsoneObj)
            zone.addErrback(self._createZoneFailure, zoneName, records, self.nsoneObj)
            dl.append(zone)
        return defer.DeferredList(dl, fireOnOneErrback=True)


    @defer.inlineCallbacks
    def _createZone(self, zoneName):
        """
        Returns the result of the deferred zone api call when available.

        Args:
            zoneName (str): The zone name in the data dictionary

        Returns:
            nsone.zones.Zone
        """

        zone = yield self.nsoneObj.createZone(zoneName)
        defer.returnValue(zone)


    def _createZoneSuccess(self, response, zoneName, records, nsoneObj):
        """
        Success callback for _createZone deferred object.
        Triggered if there are no errors when calling the api.

        If a zone is created successfully, then the next logical step
        during the import process is to add all of the records for that zone

        This method calls _createRecords which creates
        deferred objects for all of the records in the record list and adde
        both success and error callbacks for each instance.

        Each deferred record is tracked with the DeferredList object
        and the error back is fired as soon as one error back is fired

        Args:
            response (nsone.zones.Zone): The zone returned from createZone
            zoneName (str):  The zone name
            records (list): The list of records belonging to the zone
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Returns:
            defer.DeferredList
        """
        return self._createRecords(response, zoneName, records, nsoneObj)


    @defer.inlineCallbacks
    def _createZoneFailure(self, failure, zoneName, records, nsoneObj):
        """
        Failure Error callback if a zone cannot be created

        If a zone fails to be created, it is likely due to the fact that
        it exists already. The next logical step is to try to load the existing zone.

        A deferred zone is created with the _loadZone method. If a zone is loaded
        successfully, the _loadZoneSuccess callback is fired. Othewise, the error
        callback is fired

        A deferred zone object is yielded and the response from _loadZone is returned
        to the generator when it is available.


        Args:
            failure (twisted.python.failure)
            zoneName (str):  The zone name
            records (list): The list of records belonging to the zone
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Yields:
            twisted.internet.defer
        """

        f = failure.trap(ResourceException)
        print failure.getErrorMessage()

        zone = self._loadZone(zoneName, nsoneObj)
        zone.addCallback(self._loadZoneSuccess, zoneName, records, nsoneObj)
        zone.addErrback(self._loadZoneFailure, zoneName)
        yield zone


    @defer.inlineCallbacks
    def _loadZone(self, zoneName, nsoneObj):
        """
        Gets the result of the deferred load zone api call when available.

        Args:
            zoneName (str): The zone name in the data dictionary
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Returns:
            nsone.zones.Zone
        """

        zone = yield nsoneObj.loadZone(zoneName)
        defer.returnValue(zone)


    def _loadZoneSuccess(self, response, zoneName, records, nsoneObj):
        """
        Success callback for _loadZone deferred object.
        Triggered if there are no errors when calling the api.

        If a zone is loaded successfully, then the next logical step
        during the import process is to add all of the records for that zone
        similar to creating a zone

        This method calls a helper method that creates deferred objects
        for all of the records  in the record list and addes both success
        and error callbacks for each instance.

        Each deferred record is tracked with the DeferredList object
        and the error back is fired as soon as one error back is fired

        Args:
            response (nsone.zones.Zone): The zone returned from createZone
            zoneName (str):  The zone name
            records (list): The list of records belonging to the zone
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Returns:
            defer.DeferredList
        """

        print 'Successfully Loaded Zone: {}'.format(zoneName)

        return self._createRecords(response, zoneName, records, nsoneObj)


    def _loadZoneFailure(self, failure, zoneName):
        """
        Triggered when a zone cannot be loaded
        Prints the error message from the failure

        Args:
            failure (twisted.python.failure):
            zoneName (str):  The zone name
        """

        print '{}: {}'.format(zoneName, failure.getErrorMessage())


    def _createRecords(self, response, zoneName, records, nsoneObj):
        """
        This method reates deferred objects
        for all of the records  in the record list and addes both success
        and error callbacks for each instance.

        Records are logically created either after creating a zone
        or loading a zone successfully which is why this functionality
        is modularized into this function to remove duplicate logic.

        Each deferred record is tracked with the DeferredList object
        and the error back is fired as soon as one error back is fired

        Args:
            response (nsone.zones.Zone): The zone returned from createZone
            zoneName (str):  The zone name
            records (list): The list of records belonging to the zone
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Returns:
            defer.DeferredList
        """

        dl = []
        zone = response
        for rec in records:
            answers = rec['Data'].split()
            methodName = 'add_{}'.format(rec['Type'])
            addMethod = getattr(zone, methodName)

            record = self._createRecord(addMethod, zoneName, [answers], rec['TTL'])
            record.addCallback(self._createRecordSuccess)
            record.addErrback(self._createRecordFailure, zoneName, rec['Type'], answers, nsoneObj)
            dl.append(record)
        return defer.DeferredList(dl, fireOnOneErrback=True)


    @defer.inlineCallbacks
    def _createRecord(self, addMethod, zoneName, answers, ttl):
        """
        Calls the add_X method on zones for creating records and
        returns the value when it's available

        Args:
            addMethod (function) : add_X method of the zone where X is dynamic
            zoneName (str): The zone name from the data dict
            answers (list): The answers for the record in list form
            ttl (str): The TTL value for the record

        Return:
            nsone.records.Record
        """
        record = yield addMethod(zoneName, answers, ttl=ttl)
        defer.returnValue(record)


    def _createRecordSuccess(self, response):
        """
        Triggered when a record is created successfully

        If a record is created successfully, an nsone record instance is returned

        Args:
            response (nsone.records.Record): an instance of an nsone record object
        """
        print 'Created record: {}'.format(response)


    @defer.inlineCallbacks
    def _createRecordFailure(self, failure, zoneName, recType, answers, nsoneObj):
        """
        Triggered when a record cannot be created.

        Logically if a record can't be created, an attempt at loading it is made.
        A deferred record object is created and both success and error callbacks
        are chained onto it.


        Args:
            failure (twisted.python.failure): the failure object

        Yields:
            nsone.records.Record

        """
        f = failure.trap(ResourceException)
        if f == ResourceException:
            record = self._loadRecord(zoneName, recType, nsoneObj)
            record.addCallback(self._loadRecordSuccess, answers)
            record.addErrback(self._loadRecordFailure)
            yield record


    @defer.inlineCallbacks
    def _loadRecord(self, zoneName, recType, nsoneObj):
        """
        Calls the loadRecord  method on nsoneObj
        returns the value of the record when it's available

        Args:
            zoneName (str): The zone name from the data dict
            recType (str): The record type
            nsoneObj (nsone.NSONE): Instance of the nsone object

        Return:
            nsone.records.Record
        """

        record = yield nsoneObj.loadRecord(zoneName, recType, zoneName)
        defer.returnValue(record)


    @defer.inlineCallbacks
    def _loadRecordSuccess(self, response, answers):
        """
        Triggered when a record is successfully loaded

        Logically if a record is loaded the next step would be to
        try to add answers to it.

        A deferred object is yielded and the response from the
        addAnswers method on the record is returned to the generator
        when available. The response from the method triggers either
        the succes or error callback on the deferred object.

        Args:
            response (nsone.records.Record): the record instance
            answers (list): The answers to be added to the record

        Yields:
            twisted.internet.defer

        """

        print 'Successfully loaded Record: {}'.format(response)
        record = response
        addRecordAnswersRes = self._addRecordAnswers(record, answers)
        addRecordAnswersRes.addCallback(self._addRecordAnswersSuccess, answers)
        addRecordAnswersRes.addErrback(self._addRecordAnswersFailure)
        yield addRecordAnswersRes


    def _loadRecordFailure(self, failure):
        """
        Prints the failure message if a record fails to load

        Args:
            failure (twisted.python.failure): The failure object
        """
        print failure.getErrorMessage()


    @defer.inlineCallbacks
    def _addRecordAnswers(self, record, answers):
        """
        Calls the addAnswers method on the nsone.records.Record object

        If the record answers already contain the answers passed
        into this method, then nothing is done. Otherwise, the
        addAnswers method is called and the answers are added to
        the record

        Returns a deferred object with the response from the
        addAnswers method on the record object when it is available
        or returns None if the record answers intersect with
        what's passed in here.

        Args:
            record (nsone.records.Record): The nsone record object
            answers (list): The record answers

        Yields:
            None
        """

        recordData = yield record.data
        recordAnswers = {answer['answer'][0] for answer in recordData['answers']}
        if not recordAnswers.intersection(answers):
            print 'Adding answer: {}'.format(answers)
            yield record.addAnswers(answers)
        else:
            print 'Answer already exists: {}'.format(answers[0])


    def _addRecordAnswersSuccess(self, response, answers):
        """
        Prints a success message to show that the answers were added successfully.

        Args:
            response (None): the addAnswers method on the record returns None on success
            answers (list): The record answers

        """
        print 'Successfully processed answers: {}'.format(answers)


    def _addRecordAnswersFailure(self, failure):
        """
        Prints a failure message to show that the answers weren't added

        Args:
            failure (twisted.python.failure): the twisted failure object

        """
        print failure.getErrorMessage()


    def _startRequests(self, reactor):
        """
        This method initializes either the zone data import or deletion.

        All of the api requests are triggered here

        Args:
            reactor (twisted.internet.reactor)

        Return:
            function
        """

        if self.deleteData:
            return self._deleteZoneData()
        return self._importZoneData()


    def run(self):
        """
        Schedules the startRequests method and gracefully exits the program when either
        all of the deferred objects fire successfully or fail
        """

        task.react(self._startRequests)
コード例 #10
0
ファイル: ns1.py プロジェクト: stokkie90/octodns
class Ns1Provider(BaseProvider):
    '''
    Ns1 provider

    nsone:
        class: octodns.provider.ns1.Ns1Provider
        api_key: env/NS1_API_KEY
    '''
    SUPPORTS_GEO = True
    SUPPORTS = set(('A', 'AAAA', 'ALIAS', 'CAA', 'CNAME', 'MX', 'NAPTR', 'NS',
                    'PTR', 'SPF', 'SRV', 'TXT'))

    ZONE_NOT_FOUND_MESSAGE = 'server error: zone not found'

    def __init__(self, id, api_key, *args, **kwargs):
        self.log = getLogger('Ns1Provider[{}]'.format(id))
        self.log.debug('__init__: id=%s, api_key=***', id)
        super(Ns1Provider, self).__init__(id, *args, **kwargs)
        self._client = NSONE(apiKey=api_key)

    def _data_for_A(self, _type, record):
        # record meta (which would include geo information is only
        # returned when getting a record's detail, not from zone detail
        geo = defaultdict(list)
        data = {
            'ttl': record['ttl'],
            'type': _type,
        }
        values, codes = [], []
        if 'answers' not in record:
            values = record['short_answers']
        for answer in record.get('answers', []):
            meta = answer.get('meta', {})
            if meta:
                # country + state and country + province are allowed
                # in that case though, supplying a state/province would
                # be redundant since the country would supercede in when
                # resolving the record.  it is syntactically valid, however.
                country = meta.get('country', [])
                us_state = meta.get('us_state', [])
                ca_province = meta.get('ca_province', [])
                for cntry in country:
                    cn = transformations.cc_to_cn(cntry)
                    con = transformations.cn_to_ctca2(cn)
                    key = '{}-{}'.format(con, cntry)
                    geo[key].extend(answer['answer'])
                for state in us_state:
                    key = 'NA-US-{}'.format(state)
                    geo[key].extend(answer['answer'])
                for province in ca_province:
                    key = 'NA-CA-{}'.format(province)
                    geo[key].extend(answer['answer'])
                for code in meta.get('iso_region_code', []):
                    key = code
                    geo[key].extend(answer['answer'])
            else:
                values.extend(answer['answer'])
                codes.append([])
        values = [unicode(x) for x in values]
        geo = OrderedDict(
            {unicode(k): [unicode(x) for x in v]
             for k, v in geo.items()})
        data['values'] = values
        data['geo'] = geo
        return data

    _data_for_AAAA = _data_for_A

    def _data_for_SPF(self, _type, record):
        values = [v.replace(';', '\\;') for v in record['short_answers']]
        return {'ttl': record['ttl'], 'type': _type, 'values': values}

    _data_for_TXT = _data_for_SPF

    def _data_for_CAA(self, _type, record):
        values = []
        for answer in record['short_answers']:
            flags, tag, value = answer.split(' ', 2)
            values.append({
                'flags': flags,
                'tag': tag,
                'value': value,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_CNAME(self, _type, record):
        try:
            value = record['short_answers'][0]
        except IndexError:
            value = None
        return {
            'ttl': record['ttl'],
            'type': _type,
            'value': value,
        }

    _data_for_ALIAS = _data_for_CNAME
    _data_for_PTR = _data_for_CNAME

    def _data_for_MX(self, _type, record):
        values = []
        for answer in record['short_answers']:
            preference, exchange = answer.split(' ', 1)
            values.append({
                'preference': preference,
                'exchange': exchange,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NAPTR(self, _type, record):
        values = []
        for answer in record['short_answers']:
            order, preference, flags, service, regexp, replacement = \
                answer.split(' ', 5)
            values.append({
                'flags': flags,
                'order': order,
                'preference': preference,
                'regexp': regexp,
                'replacement': replacement,
                'service': service,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NS(self, _type, record):
        return {
            'ttl':
            record['ttl'],
            'type':
            _type,
            'values': [
                a if a.endswith('.') else '{}.'.format(a)
                for a in record['short_answers']
            ],
        }

    def _data_for_SRV(self, _type, record):
        values = []
        for answer in record['short_answers']:
            priority, weight, port, target = answer.split(' ', 3)
            values.append({
                'priority': priority,
                'weight': weight,
                'port': port,
                'target': target,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def populate(self, zone, target=False, lenient=False):
        self.log.debug('populate: name=%s, target=%s, lenient=%s', zone.name,
                       target, lenient)

        try:
            nsone_zone = self._client.loadZone(zone.name[:-1])
            records = nsone_zone.data['records']
            geo_records = nsone_zone.search(has_geo=True)
            exists = True
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            records = []
            geo_records = []
            exists = False

        before = len(zone.records)
        # geo information isn't returned from the main endpoint, so we need
        # to query for all records with geo information
        zone_hash = {}
        for record in chain(records, geo_records):
            _type = record['type']
            if _type not in self.SUPPORTS:
                continue
            data_for = getattr(self, '_data_for_{}'.format(_type))
            name = zone.hostname_from_fqdn(record['domain'])
            record = Record.new(zone,
                                name,
                                data_for(_type, record),
                                source=self,
                                lenient=lenient)
            zone_hash[(_type, name)] = record
        [zone.add_record(r) for r in zone_hash.values()]
        self.log.info('populate:   found %s records, exists=%s',
                      len(zone.records) - before, exists)
        return exists

    def _params_for_A(self, record):
        params = {'answers': record.values, 'ttl': record.ttl}
        if hasattr(record, 'geo'):
            # purposefully set non-geo answers to have an empty meta,
            # so that we know we did this on purpose if/when troubleshooting
            params['answers'] = [{
                "answer": [x],
                "meta": {}
            } for x in record.values]
            has_country = False
            for iso_region, target in record.geo.items():
                key = 'iso_region_code'
                value = iso_region
                if not has_country and \
                   len(value.split('-')) > 1:  # pragma: nocover
                    has_country = True
                for answer in target.values:
                    params['answers'].append(
                        {
                            'answer': [answer],
                            'meta': {
                                key: [value]
                            },
                        }, )
            params['filters'] = []
            if has_country:
                params['filters'].append({"filter": "shuffle", "config": {}})
                params['filters'].append({
                    "filter": "geotarget_country",
                    "config": {}
                })
                params['filters'].append({
                    "filter": "select_first_n",
                    "config": {
                        "N": 1
                    }
                })
        self.log.debug("params for A: %s", params)
        return params

    _params_for_AAAA = _params_for_A
    _params_for_NS = _params_for_A

    def _params_for_SPF(self, record):
        # NS1 seems to be the only provider that doesn't want things
        # escaped in values so we have to strip them here and add
        # them when going the other way
        values = [v.replace('\\;', ';') for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    _params_for_TXT = _params_for_SPF

    def _params_for_CAA(self, record):
        values = [(v.flags, v.tag, v.value) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_CNAME(self, record):
        return {'answers': [record.value], 'ttl': record.ttl}

    _params_for_ALIAS = _params_for_CNAME
    _params_for_PTR = _params_for_CNAME

    def _params_for_MX(self, record):
        values = [(v.preference, v.exchange) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_NAPTR(self, record):
        values = [(v.order, v.preference, v.flags, v.service, v.regexp,
                   v.replacement) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_SRV(self, record):
        values = [(v.priority, v.weight, v.port, v.target)
                  for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _get_name(self, record):
        return record.fqdn[:-1] if record.name == '' else record.name

    def _apply_Create(self, nsone_zone, change):
        new = change.new
        name = self._get_name(new)
        _type = new._type
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        meth = getattr(nsone_zone, 'add_{}'.format(_type))
        try:
            meth(name, **params)
        except RateLimitException as e:
            period = float(e.period)
            self.log.warn(
                '_apply_Create: rate limit encountered, pausing '
                'for %ds and trying again', period)
            sleep(period)
            meth(name, **params)

    def _apply_Update(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        new = change.new
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        try:
            record.update(**params)
        except RateLimitException as e:
            period = float(e.period)
            self.log.warn(
                '_apply_Update: rate limit encountered, pausing '
                'for %ds and trying again', period)
            sleep(period)
            record.update(**params)

    def _apply_Delete(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        try:
            record.delete()
        except RateLimitException as e:
            period = float(e.period)
            self.log.warn(
                '_apply_Delete: rate limit encountered, pausing '
                'for %ds and trying again', period)
            sleep(period)
            record.delete()

    def _apply(self, plan):
        desired = plan.desired
        changes = plan.changes
        self.log.debug('_apply: zone=%s, len(changes)=%d', desired.name,
                       len(changes))

        domain_name = desired.name[:-1]
        try:
            nsone_zone = self._client.loadZone(domain_name)
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            self.log.debug('_apply:   no matching zone, creating')
            nsone_zone = self._client.createZone(domain_name)

        for change in changes:
            class_name = change.__class__.__name__
            getattr(self, '_apply_{}'.format(class_name))(nsone_zone, change)
コード例 #11
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:

# from nsone import Config
# config = Config()
# config.createFromAPIKey('qACMD09OJXBxT7XOuRs8')
# nsone = NSONE(config=config)

# create a zone to play in
zone = nsone.createZone('testzone.com')

# create an NSONE API data source
sourceAPI = nsone.datasource()
s = sourceAPI.create('my api source', 'nsone_v1')
sourceID = s['id']

# create feeds which will drive the meta data for each answer
# we'll use the id of these feeds when we connect the feeds to the
# answer meta below
feedAPI = nsone.datafeed()
feed1 = feedAPI.create(sourceID,
コード例 #12
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:

# from nsone import Config
# config = Config()
# config.createFromAPIKey('qACMD09OJXBxT7XOuRs8')
# nsone = NSONE(config=config)

# create a zone to play in
zone = nsone.createZone('testzone.com')

# create an NSONE API data source
sourceAPI = nsone.datasource()
s = sourceAPI.create('my api source', 'nsone_v1')
sourceID = s['id']

# create feeds which will drive the meta data for each answer
# we'll use the id of these feeds when we connect the feeds to the
# answer meta below
feedAPI = nsone.datafeed()
feed1 = feedAPI.create(sourceID,
コード例 #13
0
ファイル: ns1.py プロジェクト: yangvipguang/octodns
class Ns1Provider(BaseProvider):
    '''
    Ns1 provider

    nsone:
        class: octodns.provider.ns1.Ns1Provider
        api_key: env/NS1_API_KEY
    '''
    SUPPORTS_GEO = False
    SUPPORTS = set(('A', 'AAAA', 'ALIAS', 'CAA', 'CNAME', 'MX', 'NAPTR', 'NS',
                    'PTR', 'SPF', 'SRV', 'TXT'))

    ZONE_NOT_FOUND_MESSAGE = 'server error: zone not found'

    def __init__(self, id, api_key, *args, **kwargs):
        self.log = getLogger('Ns1Provider[{}]'.format(id))
        self.log.debug('__init__: id=%s, api_key=***', id)
        super(Ns1Provider, self).__init__(id, *args, **kwargs)
        self._client = NSONE(apiKey=api_key)

    def _data_for_A(self, _type, record):
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': record['short_answers'],
        }

    _data_for_AAAA = _data_for_A

    def _data_for_SPF(self, _type, record):
        values = [v.replace(';', '\;') for v in record['short_answers']]
        return {'ttl': record['ttl'], 'type': _type, 'values': values}

    _data_for_TXT = _data_for_SPF

    def _data_for_CAA(self, _type, record):
        values = []
        for answer in record['short_answers']:
            flags, tag, value = answer.split(' ', 2)
            values.append({
                'flags': flags,
                'tag': tag,
                'value': value,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_CNAME(self, _type, record):
        return {
            'ttl': record['ttl'],
            'type': _type,
            'value': record['short_answers'][0],
        }

    _data_for_ALIAS = _data_for_CNAME
    _data_for_PTR = _data_for_CNAME

    def _data_for_MX(self, _type, record):
        values = []
        for answer in record['short_answers']:
            preference, exchange = answer.split(' ', 1)
            values.append({
                'preference': preference,
                'exchange': exchange,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NAPTR(self, _type, record):
        values = []
        for answer in record['short_answers']:
            order, preference, flags, service, regexp, replacement = \
                answer.split(' ', 5)
            values.append({
                'flags': flags,
                'order': order,
                'preference': preference,
                'regexp': regexp,
                'replacement': replacement,
                'service': service,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def _data_for_NS(self, _type, record):
        return {
            'ttl':
            record['ttl'],
            'type':
            _type,
            'values': [
                a if a.endswith('.') else '{}.'.format(a)
                for a in record['short_answers']
            ],
        }

    def _data_for_SRV(self, _type, record):
        values = []
        for answer in record['short_answers']:
            priority, weight, port, target = answer.split(' ', 3)
            values.append({
                'priority': priority,
                'weight': weight,
                'port': port,
                'target': target,
            })
        return {
            'ttl': record['ttl'],
            'type': _type,
            'values': values,
        }

    def populate(self, zone, target=False, lenient=False):
        self.log.debug('populate: name=%s, target=%s, lenient=%s', zone.name,
                       target, lenient)

        try:
            nsone_zone = self._client.loadZone(zone.name[:-1])
            records = nsone_zone.data['records']
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            records = []

        before = len(zone.records)
        for record in records:
            _type = record['type']
            data_for = getattr(self, '_data_for_{}'.format(_type))
            name = zone.hostname_from_fqdn(record['domain'])
            record = Record.new(zone,
                                name,
                                data_for(_type, record),
                                source=self,
                                lenient=lenient)
            zone.add_record(record)

        self.log.info('populate:   found %s records',
                      len(zone.records) - before)

    def _params_for_A(self, record):
        return {'answers': record.values, 'ttl': record.ttl}

    _params_for_AAAA = _params_for_A
    _params_for_NS = _params_for_A

    def _params_for_SPF(self, record):
        # NS1 seems to be the only provider that doesn't want things escaped in
        # values so we have to strip them here and add them when going the
        # other way
        values = [v.replace('\;', ';') for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    _params_for_TXT = _params_for_SPF

    def _params_for_CAA(self, record):
        values = [(v.flags, v.tag, v.value) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_CNAME(self, record):
        return {'answers': [record.value], 'ttl': record.ttl}

    _params_for_ALIAS = _params_for_CNAME
    _params_for_PTR = _params_for_CNAME

    def _params_for_MX(self, record):
        values = [(v.preference, v.exchange) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_NAPTR(self, record):
        values = [(v.order, v.preference, v.flags, v.service, v.regexp,
                   v.replacement) for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _params_for_SRV(self, record):
        values = [(v.priority, v.weight, v.port, v.target)
                  for v in record.values]
        return {'answers': values, 'ttl': record.ttl}

    def _get_name(self, record):
        return record.fqdn[:-1] if record.name == '' else record.name

    def _apply_Create(self, nsone_zone, change):
        new = change.new
        name = self._get_name(new)
        _type = new._type
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        meth = getattr(nsone_zone, 'add_{}'.format(_type))
        try:
            meth(name, **params)
        except RateLimitException as e:
            self.log.warn(
                '_apply_Create: rate limit encountered, pausing '
                'for %ds and trying again', e.period)
            sleep(e.period)
            meth(name, **params)

    def _apply_Update(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        new = change.new
        params = getattr(self, '_params_for_{}'.format(_type))(new)
        try:
            record.update(**params)
        except RateLimitException as e:
            self.log.warn(
                '_apply_Update: rate limit encountered, pausing '
                'for %ds and trying again', e.period)
            sleep(e.period)
            record.update(**params)

    def _apply_Delete(self, nsone_zone, change):
        existing = change.existing
        name = self._get_name(existing)
        _type = existing._type
        record = nsone_zone.loadRecord(name, _type)
        try:
            record.delete()
        except RateLimitException as e:
            self.log.warn(
                '_apply_Delete: rate limit encountered, pausing '
                'for %ds and trying again', e.period)
            sleep(e.period)
            record.delete()

    def _apply(self, plan):
        desired = plan.desired
        changes = plan.changes
        self.log.debug('_apply: zone=%s, len(changes)=%d', desired.name,
                       len(changes))

        domain_name = desired.name[:-1]
        try:
            nsone_zone = self._client.loadZone(domain_name)
        except ResourceException as e:
            if e.message != self.ZONE_NOT_FOUND_MESSAGE:
                raise
            self.log.debug('_apply:   no matching zone, creating')
            nsone_zone = self._client.createZone(domain_name)

        for change in changes:
            class_name = change.__class__.__name__
            getattr(self, '_apply_{}'.format(class_name))(nsone_zone, change)
コード例 #14
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

# load a zone
zone = nsone.loadZone('test.com')

# create a complex record
zone.add_A('complex',
           [{'answer': ['1.1.1.1'],
             'meta': {
                 'up': False,
                 'country': ['US']
                 }
             },
            {'answer': ['9.9.9.9'],
             'meta': {
                 'up': True,
コード例 #15
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

# import a zone from the included example zone definition
zone = nsone.createZone('example2.com', zoneFile='./importzone.db')
print(zone)

# delete a whole zone, including all records, data feeds, etc. this is
# immediate and irreversible, so be careful!
zone.delete()
コード例 #16
0
ファイル: stats.py プロジェクト: quakehead/nsone-python
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

zone = nsone.loadZone("test.com")
qps = zone.qps()
print("current QPS for test.com: %s" % qps["qps"])
usage = zone.usage()
print("test.com usage: %s" % usage)
usage = zone.usage(period="30d")
print("test.com 30 d usage: %s" % usage)

rec = zone.loadRecord("foo", "A")
rqps = rec.qps()
print("current QPS for foo.test.com: %s" % rqps["qps"])
usage = rec.usage()
print("foo.test.com usage: %s" % usage)
usage = rec.usage(period="30d")
コード例 #17
0
def main():
    args = docopt(__doc__, version=BANNER, options_first=True)

    verbosity = args.get('-v', 0)
    if verbosity > 1:
        logging.basicConfig(level=logging.DEBUG)
    elif verbosity > 0:
        logging.basicConfig(level=logging.INFO)
    else:
        logging.basicConfig(level=logging.CRITICAL)
    # tweak requests logging
    if verbosity < 2:
        requests_log = logging.getLogger("requests")
        requests_log.setLevel(logging.WARNING)

    # if api key given, use a custom config
    config = None
    if args['--key']:
        config = Config()
        # this will save a .nsone with this key if one doesn't already exist
        config.createFromAPIKey(args['--key'], maybeWriteDefault=True)
        config['verbosity'] = verbosity

    try:
        nsone = NSONE(config=config)
    except ConfigException as e:
        print(e.message)
        sys.exit(1)
    except IOError as e:
        print('No config file was found. Either specify an API key (with -k) '
              'on the command line, or create %s' % Config.DEFAULT_CONFIG_FILE)
        sys.exit(1)

    # do config overrides in nsone based on cmd args
    if args['--format']:
        nsone.config['cli']['output_format'] = args['--format']

    # do defaults
    if 'output_format' not in nsone.config.get('cli', {}):
        nsone.config['cli']['output_format'] = 'text'

    if args['--endpoint']:
        nsone.config['endpoint'] = args['--endpoint']

    if args['--ignore-ssl-errors']:
        nsone.config['ignore-ssl-errors'] = args['--ignore-ssl-errors']
        if verbosity < 2:
            logging.captureWarnings(True)

    if args['--transport']:
        nsone.config['transport'] = args['--transport']

    BaseCommand.nsone = nsone

    cmd = args['<command>']

    if not cmd:
        info = "\nType 'help' for help\n\nCurrent Key: %s\nEndpoint: %s" % \
               (nsone.config.getCurrentKeyID(), nsone.config.getEndpoint())
        repl = NS1Repl(cmdListDoc, cmdList)
        repl.interact(BANNER + info)
        sys.exit(0)
    cmdArgs = args['<args>']
    subArgv = [cmd] + cmdArgs

    if cmd in cmdList.keys():
        svc = cmdList[cmd]
        try:
            subArgs = docopt(svc.__doc__, argv=subArgv, options_first=True)
        except DocoptExit as e:
            if cmd == 'help':
                print(__doc__)
            else:
                print(e.usage)
            sys.exit(1)
        try:
            svc.run(subArgs)
        except ResourceException as e:
            print('REST API error: %s' % e.message)
        except CommandException as e:
            print(e.message)
            sys.exit(1)
    else:
        exit("%r is not a command. See 'ns1 help'." % cmd)
コード例 #18
0
ファイル: config.py プロジェクト: tomprince/nsone-python
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE, Config

# you can either build your own config, or let NSONE build a default one for
# you. the latter is easier and works like this:

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
nsone = NSONE(configFile='/etc/nsone/api.json')

# to load a specific keyID inside of your config file (see config format
# in docs), use this. this only makes sense for config file loads, not
# apiKey loads:
nsone = NSONE(keyID='all-access')

# if you have special needs, build your own Config object and pass it to
# NSONE:
config = Config()
config.createFromAPIKey('qACMD09OJXBxT7XOwv9v')
config['verbosity'] = 5
config['transport'] = 'twisted'
コード例 #19
0
ファイル: nsone_factory.py プロジェクト: humanalgorithm/nsone
 def _build_nsone(self):
     config = Config()
     config[self._transport_key] = self._transport
     config.createFromAPIKey(self._api_key)
     self._nsone = NSONE(config=config)
     return self._nsone
コード例 #20
0
ファイル: ns1.py プロジェクト: stokkie90/octodns
 def __init__(self, id, api_key, *args, **kwargs):
     self.log = getLogger('Ns1Provider[{}]'.format(id))
     self.log.debug('__init__: id=%s, api_key=***', id)
     super(Ns1Provider, self).__init__(id, *args, **kwargs)
     self._client = NSONE(apiKey=api_key)
コード例 #21
0
ファイル: stats.py プロジェクト: tomprince/nsone-python
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from nsone import NSONE

# NSONE will use config in ~/.nsone by default
nsone = NSONE()

# to specify an apikey here instead, use:
# nsone = NSONE(apiKey='qACMD09OJXBxT7XOuRs8')

# to load an alternate configuration file:
# nsone = NSONE(configFile='/etc/nsone/api.json')

zone = nsone.loadZone('test.com')
qps = zone.qps()
print("current QPS for test.com: %s" % qps['qps'])
usage = zone.usage()
print("test.com usage: %s" % usage)
usage = zone.usage(period='30d')
print("test.com 30 d usage: %s" % usage)

rec = zone.loadRecord('foo', 'A')
rqps = rec.qps()
print("current QPS for foo.test.com: %s" % rqps['qps'])
usage = rec.usage()
print("foo.test.com usage: %s" % usage)
usage = rec.usage(period='30d')