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)
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)
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 = {}
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
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
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
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)
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
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)
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)
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'])
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])
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"])
# # 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
def test_rest_interface(ns1_config, method, want): client = NS1(config=ns1_config) got = getattr(client, method)() assert isinstance(got, want)
def __init__(self, api_key): self.api = NS1(apiKey=api_key)
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')
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)
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()
# 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()
# # 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"
# # 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'
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"])):