Example #1
0
 def _build_ns1(self):
     self.config = Config()
     self.config.createFromAPIKey(self.module.params["apiKey"])
     self.config["transport"] = "basic"
     if self.module.params["endpoint"]:
         self.config["endpoint"] = self.module.params["endpoint"]
     if self.module.params["ignore_ssl"]:
         self.config["ignore-ssl-errors"] = self.module.params["ignore_ssl"]
     self.ns1 = NS1(config=self.config)
Example #2
0
def init_api():
    """
    Inititialize NS1 SDK

    :return: Configured NS1 API object
    """
    config = Config()
    config.createFromAPIKey(ns1_apikey)
    config["endpoint"] = ns1_endpoint
    return NS1(config=config)
Example #3
0
 def __init__(self, id, api_key, nameservers=[], *args, **kwargs):
     self.log = getLogger('Ns1Provider[{}]'.format(id))
     self.log.debug('__init__: id=%s, api_key=***', id)
     self.nameservers = nameservers
     super(Ns1Provider, self).__init__(id, *args, **kwargs)
     _NS1 = NS1(apiKey=api_key)
     self._NS1Records = _NS1.records()
     self._NS1Zones = _NS1.zones()
     self._zone_cache = {}
     self._record_cache = {}
Example #4
0
    def __init__(self,
                 api_key,
                 parallelism=None,
                 retry_count=4,
                 client_config=None):
        self.log.debug(
            '__init__: parallelism=%s, retry_count=%d, '
            'client_config=%s', parallelism, retry_count, client_config)
        self.retry_count = retry_count

        client = NS1(apiKey=api_key)

        # NS1 rate limits via a "token bucket" scheme, and provides information
        # about rate limiting in headers on responses. Token bucket can be
        # thought of as an initially "full" bucket, where, if not full, tokens
        # are added at some rate. This allows "bursting" requests until the
        # bucket is empty, after which, you are limited to the rate of token
        # replenishment.
        # There are a couple of "strategies" built into the SDK to avoid 429s
        # from rate limiting. Since octodns operates concurrently via
        # `max_workers`, a concurrent strategy seems appropriate.
        # This strategy does nothing until the remaining requests are equal to
        # or less than our `parallelism`, after which, each process will sleep
        # for the token replenishment interval times parallelism.
        # For example, if we can make 10 requests in 60 seconds, a token is
        # replenished every 6 seconds. If parallelism is 3, we will burst 7
        # requests, and subsequently each process will sleep for 18 seconds
        # before making another request.
        # In general, parallelism should match the number of workers.
        if parallelism is not None:
            client.config['rate_limit_strategy'] = 'concurrent'
            client.config['parallelism'] = parallelism

        # The list of records for a zone is paginated at around ~2.5k records,
        # this tells the client to handle any of that transparently and ensure
        # we get the full list of records.
        client.config['follow_pagination'] = True

        # additional options or overrides
        if isinstance(client_config, Mapping):
            for k, v in client_config.items():
                client.config[k] = v

        self._client = client

        self._records = client.records()
        self._zones = client.zones()
        self._monitors = client.monitors()
        self._notifylists = client.notifylists()
        self._datasource = client.datasource()
        self._datafeed = client.datafeed()

        self._datasource_id = None
        self._feeds_for_monitors = None
        self._monitors_cache = None
Example #5
0
def update_record_a(ip: str) -> bool:
    ns1_api: NS1 = NS1(apiKey=NS1_API)
    record: records = ns1_api.loadRecord(DOMAIN_FOR_UPDATE, 'A')
    upd_ip = record.data['answers'][0]['answer'][0]

    if isinstance(upd_ip, str) and ip != upd_ip:
        record.update(answers=[ip])

        return True

    return False
Example #6
0
    def __init__(self, api_key, retry_count=4):
        self.log.debug('__init__: retry_count=%d', retry_count)
        self.retry_count = retry_count

        client = NS1(apiKey=api_key)
        self._records = client.records()
        self._zones = client.zones()
        self._monitors = client.monitors()
        self._notifylists = client.notifylists()
        self._datasource = client.datasource()
        self._datafeed = client.datafeed()

        self._datasource_id = None
        self._feeds_for_monitors = None
        self._monitors_cache = None
Example #7
0
def rate_limit_strategy_solo_example():
    """
    This strategy sleeps a bit after each request, based on analysis of the
    rate-limiting headers on the response. This is intended for use when we
    have a single process/worker hitting the API.
    """
    config = _get_config()
    config["rate_limit_strategy"] = "solo"

    api = NS1(config=config)
    zones_list = api.zones().list()
    for z in zones_list:
        print(z["zone"])
        zone = api.zones().retrieve(z["zone"])
        print(zone)
Example #8
0
 def _init_client(self):
     """ init_client method, run at class creation
     """
     self.logger.debug('Initializing ns1 client')
     # Check if we have an API Key in config
     try:
         api_key = self.config['api_key']
     except Exception:
         self.logger.error('Failed to find API Key in NS1 config')
     # Load the API Key into NS1()
     try:
         ns1 = NS1(apiKey=api_key)
     except Exception as e:
         self.logger.error(e)
         sys.exit(1)
     else:
         self.logger.debug('API Key loaded')
         return ns1
Example #9
0
def rate_limit_strategy_concurrent_example():
    """
    This strategy sleeps a bit after each request, based on analysis of the
    rate-limiting headers on the response, and the provided "parallelism"
    number. This is intended for use when we have multiple workers hitting the
    API concurrently.
    """
    config = _get_config()
    config["rate_limit_strategy"] = "concurrent"
    # number of workers
    config["parallelism"] = 11

    api = NS1(config=config)
    zones_list = api.zones().list()
    for z in zones_list:
        print(z["zone"])
        zone = api.zones().retrieve(z["zone"])
        print(zone)
Example #10
0
def manage_dns(domain, ip_address, subdomain, remove):
    """Add or remove an IP to our DNS zone."""
    api = NS1(apiKey=API_KEY)
    zone = api.loadZone(domain)
    record = zone.loadRecord(subdomain, "A")
    answers = [answer["answer"] for answer in record["answers"]]
    print("Old IPs for record '%s.%s': %s" % (subdomain, domain, answers))
    if remove:
        print("Removing IP: %s" % ip_address)
        answers = [
            answer for answer in answers
            if answer != ip_address and ip_address not in answer
        ]
    else:
        print("Adding IP: %s" % ip_address)
        answers.append([ip_address])
    print("New IPs for record '%s.%s': %s" % (subdomain, domain, answers))
    record.update(answers=answers)
Example #11
0
def main():
    if os.path.isfile('/config.yml') is not True:
        print('/config.yml does not exist or is not a file, exiting.')
        exit(1)

    config_file = yaml.load(open('/config.yml', 'r'))

    for domain in config_file:
        nsone_config = Config()
        nsone_config.createFromAPIKey(config_file[domain]['api-key'])
        nsone_config["transport"] = "requests"
        client = NS1(config=nsone_config)
        zone = client.loadZone(domain)

        for record in config_file[domain]['records-to-update']:
            record = zone.loadRecord(record, 'A')
            result = check_ip(record)
            if result['matches'] is False:
                set_ip(record, result['my_ip'])
Example #12
0
def main(api_key, domain, hostname=None):
    client = NS1(apiKey=api_key)
    client.config["transport"] = "requests"
    if hostname == None:
        hostname = socket.gethostname()
    zone = client.loadZone(domain)
    current_ip = requests.get("https://api.ipify.org/?format=json").json()["ip"]

    try:
        record = zone.loadRecord(hostname, 'A')
        dns_ip = record.data['answers'][0]['answer'][0]
        if current_ip != dns_ip:
            logger.info('Updating [%s.%s -> %s] ...', hostname, domain, current_ip)
            record.update(answers=[current_ip])
        else:
            logger.info('DNS record exists [%s.%s -> %s] ...', hostname, domain, current_ip)

    except:
        logger.info('Creating [%s.%s -> %s] ...', hostname, domain, current_ip)
        zone.add_A(hostname, answers=[current_ip])
Example #13
0
def main():
    if os.path.isfile('/app/config/config.yml') is not True:
        print(
            '/app/config/config.yml does not exist or is not a file, exiting.')
        exit(1)

    config_file = yaml.safe_load(open('/app/config/config.yml', 'r'))

    for domain in config_file:
        nsone_config = Config()
        nsone_config.createFromAPIKey(config_file[domain]['api-key'])
        nsone_config["transport"] = "requests"
        client = NS1(config=nsone_config)
        zone = client.loadZone(domain)

        for host in config_file[domain]['hosts']:
            for x in host["subdomains"]:
                try:
                    if x == "@":
                        host["record"] = zone.loadRecord(domain, 'A')
                    else:
                        host["record"] = zone.loadRecord(x, 'A')
                    my_ip = get_ip(host)
                    result = check_ip(my_ip, host["record"])
                    if result['matches'] is False:
                        if not config_file[domain]["test"]:
                            set_ip(host["record"], result['my_ip'])
                except rest.errors.ResourceException:
                    full_domain = domain
                    if x != "@":
                        full_domain = "{0}.{1}".format(x, domain)

                    if not config_file[domain]["test"]:
                        if "allowed_countries" not in config_file[domain]:
                            config_file[domain]["allowed_countries"] = [
                                'US', 'CA'
                            ]
                        create_record(zone, full_domain, my_ip,
                                      config_file[domain]["allowed_countries"])
Example #14
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#
import uuid

from ns1 import NS1

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

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

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

########################
# CREATE / UPDATE TEAM #
########################
teamAPI = api.team()

# create a new team
# you can also specify an ip_whitelist and permissions
# if left blank, all permissions will be defaulted to false
team = teamAPI.create("test-team")
print(team)
teamID = team["id"]

# modify some of the default permissions
Example #15
0
def test_rest_interface(ns1_config, method, want):
    client = NS1(config=ns1_config)
    got = getattr(client, method)()
    assert isinstance(got, want)
Example #16
0
 def __init__(self, api_key):
     self.api = NS1(apiKey=api_key)
Example #17
0
 def __init__(self, apikey, domain):
     # not bothering with zone
     self.api = NS1(apikey)
     self.domain = domain
     self.ip_cache = None
     self.rec = self.api.loadRecord(self.domain, 'A')
Example #18
0
 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 = NS1(apiKey=api_key)
Example #19
0
    def __init__(self, api_key, retry_count=4):
        self.retry_count = retry_count

        client = NS1(apiKey=api_key)
        self._records = client.records()
        self._zones = client.zones()
Example #20
0
# TWISTED #
###########

from ns1 import NS1, 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"
api = NS1(config=config)


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


def gotQPS(result):
    print("current QPS for test.com: %s" % result["qps"])
    reactor.stop()
Example #21
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from ns1 import NS1, Config

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

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

# to specify an apikey here instead, use:
api = NS1(apiKey="qACMD09OJXBxT7XOuRs8")

# to load an alternate configuration file:
api = NS1(configFile="/etc/ns1/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:
api = NS1(keyID="all-access")

# if you have special needs, build your own Config object and pass it to
# NS1:
config = Config()
config.createFromAPIKey("qACMD09OJXBxT7XOwv9v")
config["verbosity"] = 5
config["transport"] = "twisted"
Example #22
0
#
# Copyright (c) 2014 NSONE, Inc.
#
# License under The MIT License (MIT). See LICENSE in project root.
#

from ns1 import NS1, Config

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

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

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

# to load an alternate configuration file:
api = NS1(configFile='/etc/ns1/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:
api = NS1(keyID='all-access')

# if you have special needs, build your own Config object and pass it to
# NS1:
config = Config()
config.createFromAPIKey('qACMD09OJXBxT7XOwv9v')
config['verbosity'] = 5
config['transport'] = 'twisted'
Example #23
0
import json
from ns1 import NS1

api = NS1(apiKey='o1ZUt7O44pqTEEwnStbA')

def GetZoneInfo():
    print("Please enter the zone name")
    global zone
    zone = input("> ")
    zoneDef = api.loadZone(zone)
    double = str(zoneDef.data).replace("'", '"')
    valid = json.dumps(zoneDef.data, sort_keys=True, indent=4)
    global data
    data = json.loads(valid)
    
     #print(data["records"][2])
    
    
def getRecords():
    str(data["records"][2]["type"]).replace("'", '"')
    print("Which Record Type do You want? (A, MX, NS, ALIAS, CNAME, SPF, TXT, SRV)")
    recordType = input("> ")
    # len(data["records"])
    recordImport = []
    tf_TTL = []
    tf_Type = []
    tf_Answers = []
    tf_Domain = []
    
    
    # for n in range(0, len(data["records"])):