mirror of
				https://github.com/shokinn/hetzner-ddns-for-mikrotik.git
				synced 2025-11-03 20:18:30 +00:00 
			
		
		
		
	inital commit
This commit is contained in:
		
						commit
						b03d1ac14a
					
				
					 3 changed files with 377 additions and 0 deletions
				
			
		
							
								
								
									
										21
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					MIT License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2023 Philip Henning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
							
								
								
									
										90
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,90 @@
 | 
				
			||||||
 | 
					# hetzner-ddns-for-mikrotik
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Mikrotik RouterOS script for updating DNS entries via Hetzner's DNS API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Table of Contents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [hetzner-ddns-for-mikrotik](#hetzner-ddns-for-mikrotik)
 | 
				
			||||||
 | 
					  - [Table of Contents](#table-of-contents)
 | 
				
			||||||
 | 
					  - [How does is works?](#how-does-is-works)
 | 
				
			||||||
 | 
					  - [Setup](#setup)
 | 
				
			||||||
 | 
					    - [Script configuration data](#script-configuration-data)
 | 
				
			||||||
 | 
					      - [`domainEntryConfig` array data sheet](#domainentryconfig-array-data-sheet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How does is works?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The scripts checks the defined interfaces' IP's for the configured [FQDN's](https://en.wikipedia.org/wiki/Fully_qualified_domain_name).  
 | 
				
			||||||
 | 
					This is achieved via plain DNS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If the IP from the interface differs from the IP configures in the DNS record, the DNS record will be updated accordingly to the interfaces' IP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Dependencies
 | 
				
			||||||
 | 
					   1. This script requires [Winand](https://github.com/Winand)'s [mikrotik-json-parser](https://github.com/Winand/mikrotik-json-parser).
 | 
				
			||||||
 | 
					2. Create a new Script `System -> Scripts`
 | 
				
			||||||
 | 
					   1. Name: `ddns-hetzner`
 | 
				
			||||||
 | 
					   2. Policy: `read`, `write`, `test`, uncheck everything else
 | 
				
			||||||
 | 
					   3. Source: Copy the script here
 | 
				
			||||||
 | 
					3. Create a [API token for Hetzner's DNS API](https://dns.hetzner.com/settings/api-token)
 | 
				
			||||||
 | 
					4. Configure the script to your needs, check the description in the script or below for information how to configure it
 | 
				
			||||||
 | 
					5. Create another new script
 | 
				
			||||||
 | 
					   1. Name: `JParseFunctions`
 | 
				
			||||||
 | 
					   2. Policy: `read`, `write`, `test` uncheck everything else
 | 
				
			||||||
 | 
					   3. Source: The content of [mikrotik-json-parser](https://github.com/Winand/mikrotik-json-parser/blob/master/JParseFunctions)
 | 
				
			||||||
 | 
					6. Create a new Schedule `System -> Schedule`
 | 
				
			||||||
 | 
					   1. Name: `ddns-hetzner`
 | 
				
			||||||
 | 
					   2. Start Date: leave it as it is
 | 
				
			||||||
 | 
					   3. Start Time: leave it as it is
 | 
				
			||||||
 | 
					   4. Interval: `00:05:00`
 | 
				
			||||||
 | 
					   5. Policy: `read`, `write`, `test` uncheck everything else
 | 
				
			||||||
 | 
					   6. On Event: `ddns-hetzner`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Script configuration data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					|       Variable name |       Data type       | Example                                                                                                                                | Description                                                                                                                                                                           |
 | 
				
			||||||
 | 
					| ------------------: | :-------------------: | :------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
 | 
				
			||||||
 | 
					|            `apiKey` |       `string`        | `:local apiKey "3su1OLc0gUhUdwxn1bmKFss5V19mBhBx";`                                                                                    | This variable requires a valid API token for the [Hetzner DNS API](https://dns.hetzner.com/api-docs). You can create an [API token here](https://dns.hetzner.com/settings/api-token). |
 | 
				
			||||||
 | 
					| `domainEntryConfig` | `array`s of `string`s | `:local domainEntryConfig {{"pppoe-out1";"";"domain.com";"A";"@";"300";};{"pppoe-out1";"pool-ipv6";"domain.com";"AAAA";"@";"300";};};` | See below how to format the arrays correctly.                                                                                                                                         |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### `domainEntryConfig` array data sheet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `domainEntryConfig` array consists of multiple arrays. Each of the is configuring a DNS record for a given domain in a zone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The data sheet below describes the formatting of the DNS records arrays.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Array index | Data          | Data type | Example        | Description                                                                                                                                                              |
 | 
				
			||||||
 | 
					| ----------: | :------------ | :-------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | 
				
			||||||
 | 
					|         `0` | `interface`   | `string`  | `"pppoe-out1"` | Name of the interface where the IP which is currently configured is fetched from.                                                                                        |
 | 
				
			||||||
 | 
					|         `1` | `pool`        | `string`  | `"pool-ipv6"`  | The prefix delegation pool which is used to automatically setup the IPv6 interface IP. Use "" when you don't use a pool to set your interface ip or for a type A record. |
 | 
				
			||||||
 | 
					|         `2` | `zone`        | `string`  | `"domain.com"` | Zone which should be used to set a record to.                                                                                                                            |
 | 
				
			||||||
 | 
					|         `3` | `record type` | `string`  | `"A"`          | Valid values `A`, `AAAA`. The type of record which will be set. Also determines which IP (v4/v6) will be fetched.                                                        |
 | 
				
			||||||
 | 
					|         `4` | `record name` | `string`  | `"@"`          | The record name which should be updated. Use `@` for the root of your domain.                                                                                            |
 | 
				
			||||||
 | 
					|         `5` | `record TTL`  | `string`  | `"300"`        | TTL value of the record in seconds, for a dynamic entry a short lifetime like 300 is recommended.                                                                        |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					:local domainEntryConfig {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "pppoe-out1";
 | 
				
			||||||
 | 
					        "";
 | 
				
			||||||
 | 
					        "domain.com";
 | 
				
			||||||
 | 
					        "A";
 | 
				
			||||||
 | 
					        "@";
 | 
				
			||||||
 | 
					        "300";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    {"pppoe-out1";"pool-ipv6";"domain.com";"AAAA";"@";"300";};
 | 
				
			||||||
 | 
					    {"pppoe-out1";"";"example.de";"A";"ddns";"300";};
 | 
				
			||||||
 | 
					    {"pppoe-out1";"pool-ipv6";"abc.xzy";"AAAA";"ddns";"300";};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This example will create & update those DNS records:
 | 
				
			||||||
 | 
					- domain.com
 | 
				
			||||||
 | 
					  - IPv4
 | 
				
			||||||
 | 
					  - IPv6
 | 
				
			||||||
 | 
					- example.de
 | 
				
			||||||
 | 
					  - IPv4
 | 
				
			||||||
 | 
					- abc.xzy
 | 
				
			||||||
 | 
					  - IPv6
 | 
				
			||||||
							
								
								
									
										266
									
								
								ddns-hetzner.rsc
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										266
									
								
								ddns-hetzner.rsc
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,266 @@
 | 
				
			||||||
 | 
					# -------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# DDNS update script for Hetzner's DNS API
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# by Philip 'ShokiNN' Henning <mail@philip-henning.com>
 | 
				
			||||||
 | 
					# Version 1.0
 | 
				
			||||||
 | 
					# last update: 10.11.2023
 | 
				
			||||||
 | 
					# License: MIT
 | 
				
			||||||
 | 
					# -------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --- Define variables -----------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Enter all required variables and secrets here. -- All secrets are stored unencrypted!
 | 
				
			||||||
 | 
					## API Key to authenticate to Hetzners API
 | 
				
			||||||
 | 
					### Data Type: String
 | 
				
			||||||
 | 
					:local apiKey ""; # Example: "3su1OLc0gUhUdwxn1bmKFss5V19mBhBx"; -- This one is invalid, you don't need to try ;)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## --- Domain config --------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Interface
 | 
				
			||||||
 | 
					# The interface name where the IP should be fetched from
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Example: "pppoe-out1";
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Pool
 | 
				
			||||||
 | 
					# The prefix delegation pool which is used to automatically setup the IPv6 interface IP
 | 
				
			||||||
 | 
					# Use "" when you don't use a pool to set your interface ip or for a type A record
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Example: "pool-ipv6";
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Zone
 | 
				
			||||||
 | 
					# Zone which should be used to set a record to
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Example: "domain.com";
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Record type
 | 
				
			||||||
 | 
					# The type of record which will be set
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Valid values: "A", "AAAA"
 | 
				
			||||||
 | 
					# Example: "A";
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Record name
 | 
				
			||||||
 | 
					# Record name to be used to set a DNS entry
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Example: "@"; -- use @ to setup an entry at the root of your domain, e.g. "domain.com"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Record TTL
 | 
				
			||||||
 | 
					# TTL value of the record in seconds, for a dynamic entry a short lifetime like 300 is recommended
 | 
				
			||||||
 | 
					# Data Type: String
 | 
				
			||||||
 | 
					# Example: "300";
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Array structure
 | 
				
			||||||
 | 
					# {
 | 
				
			||||||
 | 
					#     "pppoe-out1"; # Interface
 | 
				
			||||||
 | 
					#     ""; # Pool
 | 
				
			||||||
 | 
					#     "domain.com"; # Zone
 | 
				
			||||||
 | 
					#     "A"; # Record type
 | 
				
			||||||
 | 
					#     "@"; # Record name
 | 
				
			||||||
 | 
					#     300; # Record TTL
 | 
				
			||||||
 | 
					# };
 | 
				
			||||||
 | 
					## --------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					:local domainEntryConfig {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "pppoe-out1";
 | 
				
			||||||
 | 
					        "";
 | 
				
			||||||
 | 
					        "domain.com";
 | 
				
			||||||
 | 
					        "A";
 | 
				
			||||||
 | 
					        "@";
 | 
				
			||||||
 | 
					        "300";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    {"pppoe-out1";"pool-ipv6";"domain.com";"AAAA";"@";"300";};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					# ---------------------------------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local logPrefix "[Hetzner DDNS]";
 | 
				
			||||||
 | 
					:local apiUrl "https://dns.hetzner.com/api/v1";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local getLocalIpv4 do={
 | 
				
			||||||
 | 
					    :local ip [/ip address get [:pick [find interface="$configInterface"] 0] address];
 | 
				
			||||||
 | 
					    :return [:pick $ip 0 [:find $ip /]];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local getLocalIpv6 do={
 | 
				
			||||||
 | 
					    :local ip [/ipv6 address get [:pick [find interface="$configInterface" from-pool="$configInterfacePool" !link-local] 0] address];
 | 
				
			||||||
 | 
					    :return [:pick $ip 0 [:find $ip /]];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local getRemoteIpv4 do={
 | 
				
			||||||
 | 
					    :do {
 | 
				
			||||||
 | 
					        :local ip [:resolve "$configDomain"];
 | 
				
			||||||
 | 
					        :return "$ip";
 | 
				
			||||||
 | 
					    } on-error={
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local getRemoveIpv6 do={
 | 
				
			||||||
 | 
					    :local result [:toarray ""]
 | 
				
			||||||
 | 
					    :local maxwait 5
 | 
				
			||||||
 | 
					    :local cnt 0
 | 
				
			||||||
 | 
					    :local listname "tmp-resolve$cnt"
 | 
				
			||||||
 | 
					    /ipv6 firewall address-list {
 | 
				
			||||||
 | 
					        :do {
 | 
				
			||||||
 | 
					            :while ([:len [find list=$listname]] > 0) do={
 | 
				
			||||||
 | 
					                :set cnt ($cnt + 1);
 | 
				
			||||||
 | 
					                :set listname "tmp-resolve$cnt";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            :set cnt 0;
 | 
				
			||||||
 | 
					            add list=$listname address=$1;
 | 
				
			||||||
 | 
					            :while ([find list=$listname && dynamic] = "" && $cnt < $maxwait) do={
 | 
				
			||||||
 | 
					                :delay 1;:set cnt ($cnt +1)
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            :foreach i in=[find list=$listname && dynamic] do={
 | 
				
			||||||
 | 
					                 :local rawip [get $i address];
 | 
				
			||||||
 | 
					                 :set result ($result, [:pick $rawip 0 [:find $rawip "/"]]);
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            remove [find list=$listname && !dynamic];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    :return $result;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local apiGetZones do={
 | 
				
			||||||
 | 
					    [/system script run "JParseFunctions"; global JSONLoad; global JSONLoads; global JSONUnload];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :local apiPage -0;
 | 
				
			||||||
 | 
					    :local apiNextPage 1;
 | 
				
			||||||
 | 
					    :local apiLastPage 0;
 | 
				
			||||||
 | 
					    :local apiResponse "";
 | 
				
			||||||
 | 
					    :local returnArr [:toarray ""];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :do {
 | 
				
			||||||
 | 
					        :set apiResponse ([/tool/fetch "$apiUrl/zones?page=$apiNextPage&search_name=$configZone" http-method=get http-header-field="Auth-API-Token:$apiKey" output=user as-value]->"data");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :set apiPage ([$JSONLoads $apiResponse]->"meta"->"pagination"->"page");
 | 
				
			||||||
 | 
					        :set apiNextPage ([$JSONLoads $apiResponse]->"meta"->"pagination"->"next_page");
 | 
				
			||||||
 | 
					        :set apiLastPage ([$JSONLoads $apiResponse]->"meta"->"pagination"->"last_page");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        :set returnArr ($returnArr , ([:toarray ([$JSONLoads $apiResponse]->"zones")]));
 | 
				
			||||||
 | 
					    } while=($apiPage != $apiLastPage);
 | 
				
			||||||
 | 
					    $JSONUnload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :return $returnArr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local apiGetZoneId do={
 | 
				
			||||||
 | 
					    :foreach responseZone in=$responseZones do={
 | 
				
			||||||
 | 
					        :if (($responseZone->"name") = $configZone) do={
 | 
				
			||||||
 | 
					            :return ($responseZone->"id");
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local apiSetRecord do={
 | 
				
			||||||
 | 
					    #apiUrl=$apiUrl apiKey=$apiKey zoneId=$zoneId configType=$configType configRecord=$configRecord configTtl=$configTtl interfaceIp=$interfaceIp
 | 
				
			||||||
 | 
					    [/system script run "JParseFunctions"; global JSONLoad; global JSONLoads; global JSONUnload];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :local recordId "";
 | 
				
			||||||
 | 
					    :local apiResponse "";
 | 
				
			||||||
 | 
					    :local payload "{\"zone_id\": \"$zoneId\",\"type\": \"$configType\",\"name\": \"$configRecord\",\"value\": \"$interfaceIp\",\"ttl\": $([:tonum $configTtl])}";
 | 
				
			||||||
 | 
					    :local records ([$JSONLoads ([/tool/fetch "$apiUrl/records?zone_id=$zoneId" http-method=get http-header-field="Auth-API-Token:$apiKey" output=user as-value]->"data")]->"records");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    :foreach record in=$records do={
 | 
				
			||||||
 | 
					        :if ((($record->"name") = $configRecord) && (($record->"type") = $configType)) do={
 | 
				
			||||||
 | 
					            :set recordId ($record->"id");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :if ($recordId != "") do={
 | 
				
			||||||
 | 
					        :set apiResponse ([/tool/fetch "$apiUrl/records/$recordId" http-method=put http-header-field="Content-Type:application/json,Auth-API-Token:$apiKey" http-data=$payload output=user as-value]->"status");
 | 
				
			||||||
 | 
					    } else={
 | 
				
			||||||
 | 
					        :set apiResponse ([/tool/fetch "$apiUrl/records" http-method=post http-header-field="Content-Type:application/json,Auth-API-Token:$apiKey" http-data=$payload output=user as-value]->"status");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $JSONUnload;
 | 
				
			||||||
 | 
					    return $apiResponse;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Log "run of script"
 | 
				
			||||||
 | 
					:log info "$logPrefix running";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:local index 0;
 | 
				
			||||||
 | 
					:foreach i in=$domainEntryConfig do={
 | 
				
			||||||
 | 
					    :local configInterface ("$($i->0)");
 | 
				
			||||||
 | 
					    :local configIpv6Pool ("$($i->1)");
 | 
				
			||||||
 | 
					    :local configZone ("$($i->2)");
 | 
				
			||||||
 | 
					    :local configType ("$($i->3)");
 | 
				
			||||||
 | 
					    :local configRecord ("$($i->4)");
 | 
				
			||||||
 | 
					    :local configTtl ("$($i->5)");
 | 
				
			||||||
 | 
					    :local configDomain "";
 | 
				
			||||||
 | 
					    :local interfaceIp "";
 | 
				
			||||||
 | 
					    :local dnsIp "";
 | 
				
			||||||
 | 
					    :local startLogMsg "$logPrefix Start configuring domain:";
 | 
				
			||||||
 | 
					    :local endLogMsg "$logPrefix Finished configuring domain:";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :if ($configRecord = "@") do={
 | 
				
			||||||
 | 
					        :set configDomain ("$($i->2)");
 | 
				
			||||||
 | 
					    } else={
 | 
				
			||||||
 | 
					        :set configDomain ("$($i->4).$($i->2)");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :if ($configType = "A") do={
 | 
				
			||||||
 | 
					        :log info "$startLogMsg $configDomain - Type A record";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :set interfaceIp [$getLocalIpv4 configInterface=$configInterface];
 | 
				
			||||||
 | 
					        :set dnsIp [$getRemoteIpv4 configDomain=$configDomain];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :if ($interfaceIp != $dnsIp) do={
 | 
				
			||||||
 | 
					            :log info "$logPrefix $configDomain: local IP ($interfaceIp) differs from DNS IP ($dnsIp) - Updating entry";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            :local responseZones [$apiGetZones apiUrl=$apiUrl apiKey=$apiKey configZone=$configZone];
 | 
				
			||||||
 | 
					            :local zoneId [$apiGetZoneId responseZones=$responseZones configZone=$configZone];
 | 
				
			||||||
 | 
					            :local responseSetRecord [$apiSetRecord apiUrl=$apiUrl apiKey=$apiKey zoneId=$zoneId configType=$configType configRecord=$configRecord configTtl=$configTtl interfaceIp=$interfaceIp];
 | 
				
			||||||
 | 
					            :if ($responseSetRecord = "finished") do={
 | 
				
			||||||
 | 
					                :log info "$logPrefix $configDomain: update successful"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        } else={
 | 
				
			||||||
 | 
					            :log info "$logPrefix $configDomain: local IP and DNS IP are equal - Nothing to do";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :log info "$endLogMsg $configDomain - Type A record";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :if ($configType = "AAAA") do={
 | 
				
			||||||
 | 
					        :log info "$startLogMsg $configDomain - Type AAAA record";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :set interfaceIp [$getLocalIpv6 configInterface=$configInterface configInterfacePool=$configIpv6Pool];
 | 
				
			||||||
 | 
					        :set dnsIp [$getRemoveIpv6 $configDomain];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :if ($interfaceIp != $dnsIp) do={
 | 
				
			||||||
 | 
					            :log info "$logPrefix $configDomain: local IP ($interfaceIp) differs from DNS IP ($dnsIp) - Updating entry";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            :local responseZones [$apiGetZones apiUrl=$apiUrl apiKey=$apiKey configZone=$configZone];
 | 
				
			||||||
 | 
					            :local zoneId [$apiGetZoneId responseZones=$responseZones configZone=$configZone];
 | 
				
			||||||
 | 
					            :local responseSetRecord [$apiSetRecord apiUrl=$apiUrl apiKey=$apiKey zoneId=$zoneId configType=$configType configRecord=$configRecord configTtl=$configTtl interfaceIp=$interfaceIp];
 | 
				
			||||||
 | 
					            :if ($responseSetRecord = "finished") do={
 | 
				
			||||||
 | 
					                :log info "$logPrefix $configDomain: update successful"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        } else={
 | 
				
			||||||
 | 
					            :log info "$logPrefix $configDomain: local IP and DNS IP are equal - Nothing to do";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :log info "$endLogMsg $configDomain - Type AAAA record";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :if (($configType != "A") && ($configType != "AAAA")) do={
 | 
				
			||||||
 | 
					        :log error ("$logPrefix Wrong record type for array index number " . $index . " (Value: $configType)");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :set index ($index+1);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					:set index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:log info "$logPrefix finished";
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue