Compare commits
8 Commits
2.2
..
1824d9f139
| Author | SHA1 | Date | |
|---|---|---|---|
| 1824d9f139 | |||
| 50b4cf105f | |||
| 1e3b545a23 | |||
| 380509c966 | |||
| 71da487aa8 | |||
| 3be6eaee0c | |||
| 5c6c8ec4ea | |||
| c7297a512c |
@@ -55,6 +55,23 @@
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
|
||||
# web frontend stack -- force LF so SRI hashes are always correct
|
||||
*.html text eol=lf
|
||||
*.htm text eol=lf
|
||||
*.css text eol=lf
|
||||
*.min.css text eol=lf
|
||||
*.js text eol=lf
|
||||
*.min.js text eol=lf
|
||||
*.php text eol=lf
|
||||
|
||||
# Visual Studio projects (Rider also)
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Serialisation
|
||||
*.json text
|
||||
*.toml text
|
||||
@@ -79,3 +96,5 @@
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.gitkeep export-ignore
|
||||
.idea export-ignore
|
||||
.vscode export-ignore
|
||||
|
||||
+34
@@ -1 +1,35 @@
|
||||
#
|
||||
# JetBrains exclusions
|
||||
#
|
||||
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
.idea/**/GitCommitMessageStorage.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# modules
|
||||
.idea_modules/
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# project-specific exclusions
|
||||
*.log
|
||||
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeveloperToolsToolWindowSettingsV1" lastSelectedContentNodeId="base64-encoder-decoder" pluginVersion="9.0.0">
|
||||
<developerToolsConfigurations />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxProjectSettings">
|
||||
<option name="commitMessageIssueKeyValidationOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
<option name="commitMessageValidationEnabledOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="com.itcodebox.notebooks.projectservice.ProjectUIState">
|
||||
<option name="selectedNotebookId" value="1" />
|
||||
<option name="selectedChapterId" value="1" />
|
||||
<option name="selectedNoteId" value="1" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="singleClickDiffPreview" value="1" />
|
||||
<option name="unhandledExceptionsIgnoreList" value="1" />
|
||||
<option name="vcsConfiguration" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# update Cloudflare DNS records with current (dynamic) IP address
|
||||
# Script by Asif Bacchus <asif@bacchus.cloud>
|
||||
# Last modified: May 10, 2021
|
||||
# Version 2.2
|
||||
# Last modified: July 19, 2026
|
||||
# Version 3.0
|
||||
#
|
||||
|
||||
### text formatting presets using tput
|
||||
@@ -157,6 +157,10 @@ scriptHelp() {
|
||||
textBlock "Switch value. Output log to console (stdout) instead of a log file. Can be combined with --nc if desired."
|
||||
textBlockDefaults "(disabled: output to log file)"
|
||||
newline
|
||||
textBlockSwitches "--log-journal"
|
||||
textBlock "Switch value. Output a structured log entry to your journaling system instead of a log file. Implies --nc."
|
||||
textBlockDefaults "(disabled: output to log file)"
|
||||
newline
|
||||
textBlockSwitches "--no-log"
|
||||
textBlock "Switch value. Do not create a log (i.e. no console, no file). You will not have *any* output from the script if you choose this option, so you will not know if updates succeeded or failed."
|
||||
textBlockDefaults "(disabled: output to log file)"
|
||||
@@ -253,6 +257,7 @@ writeLog() {
|
||||
scriptPath="$(CDPATH='' \cd -- "$(dirname -- "$0")" && pwd -P)"
|
||||
scriptName="$(basename "$0")"
|
||||
logFile="$scriptPath/${scriptName%.*}.log"
|
||||
logToJournal=0
|
||||
accountFile="$scriptPath/cloudflare.credentials"
|
||||
colourizeLogFile=1
|
||||
dnsRecords=""
|
||||
@@ -292,6 +297,10 @@ while [ $# -gt 0 ]; do
|
||||
# log to the console instead of a file
|
||||
logFile="/dev/stdout"
|
||||
;;
|
||||
--log-journal)
|
||||
# log to the journal system instead of a file
|
||||
logToJournal=1
|
||||
;;
|
||||
--no-log)
|
||||
# do not log anything
|
||||
logFile="/dev/null"
|
||||
@@ -364,6 +373,10 @@ fi
|
||||
if [ ! -f "$accountFile" ] || [ ! -s "$accountFile" ]; then
|
||||
badParam errMsg "Cannot find Cloudflare credentials file (${accountFile}). Exiting."
|
||||
fi
|
||||
if ! command -v logger >/dev/null 2>&1; then
|
||||
printf "\n%sThis script requires 'logger' be installed to write entries to your journaling system. Exiting.%s\n\n" "$err" "$norm"
|
||||
exit 2
|
||||
fi
|
||||
# turn off log file colourization if parameter is set
|
||||
if [ "$colourizeLogFile" -eq 0 ]; then
|
||||
bold=""
|
||||
@@ -378,6 +391,7 @@ fi
|
||||
|
||||
### initial log entries
|
||||
{
|
||||
|
||||
printf "%s[%s] -- Cloudflare DDNS update-script: starting --%s\n" "$ok" "$(stamp)" "$norm"
|
||||
printf "Parameters:\n"
|
||||
printf "script path: %s\n" "$scriptPath/$scriptName"
|
||||
@@ -415,7 +429,9 @@ fi
|
||||
record="${dnsRecordsToUpdate%%${dnsSeparator}*}"
|
||||
dnsRecordsToUpdate="${dnsRecordsToUpdate#*${dnsSeparator}}"
|
||||
|
||||
if [ -z "$record" ]; then continue; fi
|
||||
if [ -z "$record" ]; then
|
||||
continue
|
||||
fi
|
||||
printf "updating record: %s\n" "$record"
|
||||
done
|
||||
|
||||
@@ -459,13 +475,17 @@ while [ -n "$dnsRecordsToUpdate" ] && [ "$dnsRecordsToUpdate" != "$dnsSeparator"
|
||||
record="${dnsRecordsToUpdate%%${dnsSeparator}*}"
|
||||
dnsRecordsToUpdate="${dnsRecordsToUpdate#*${dnsSeparator}}"
|
||||
|
||||
if [ -z "$record" ]; then continue; fi
|
||||
if [ -z "$record" ]; then
|
||||
continue
|
||||
fi
|
||||
writeLog process "Processing ${record}"
|
||||
|
||||
# exit if curl/network error
|
||||
if ! cfLookup="$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records?name=${record}&type=${recordType}" \
|
||||
if ! cfLookup="$(
|
||||
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records?name=${record}&type=${recordType}" \
|
||||
-H "Authorization: Bearer ${cfKey}" \
|
||||
-H "Content-Type: application/json")"; then
|
||||
-H "Content-Type: application/json"
|
||||
)"; then
|
||||
writeLog process-error
|
||||
exitError 3
|
||||
fi
|
||||
@@ -506,10 +526,12 @@ while [ -n "$dnsRecordsToUpdate" ] && [ "$dnsRecordsToUpdate" != "$dnsSeparator"
|
||||
updateJSON="$(jq -n --arg key0 content --arg value0 "${ipAddress}" '{($key0):$value0}')"
|
||||
|
||||
# exit if curl/network error
|
||||
if ! cfResult="$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records/${objectId}" \
|
||||
if ! cfResult="$(
|
||||
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/${cfZoneId}/dns_records/${objectId}" \
|
||||
-H "Authorization: Bearer ${cfKey}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "${updateJSON}")"; then
|
||||
--data "${updateJSON}"
|
||||
)"; then
|
||||
writeLog process-error
|
||||
exitError 3
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#!/bin/sh
|
||||
|
||||
getTimeStamp() {
|
||||
(date +%F" "%T)
|
||||
}
|
||||
|
||||
# $1: message, $2: level, $3: operation, $4: code
|
||||
writeJsonLog() {
|
||||
PROGRAM_NAME="cfddns"
|
||||
DEFAULT_CODE=99
|
||||
DEFAULT_LEVEL="info"
|
||||
DEFAULT_MESSAGE="An unspecified error has occurred"
|
||||
DEFAULT_OPERATION="unspecified"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
PROPS="$(
|
||||
jq --null-input \
|
||||
--arg level "err" \
|
||||
--arg pName "$PROGRAM_NAME" \
|
||||
--arg operation "$DEFAULT_OPERATION" \
|
||||
--arg code "$DEFAULT_CODE" \
|
||||
--arg message "$DEFAULT_MESSAGE" \
|
||||
'{"level":$level, "programName":$pName, "operation":$operation, "code":$code, "message":$message}' \
|
||||
)"
|
||||
else
|
||||
PROPS="$(
|
||||
jq --null-input \
|
||||
--arg level "${2:-$DEFAULT_LEVEL}" \
|
||||
--arg pName "$PROGRAM_NAME" \
|
||||
--arg operation "${3:-$DEFAULT_OPERATION}" \
|
||||
--arg code "${4:-$DEFAULT_CODE}" \
|
||||
--arg message "$1" \
|
||||
'{"level":$level, "programName":$pName, "operation":$operation, "code":$code, "message":$message}' \
|
||||
)"
|
||||
fi
|
||||
|
||||
echo "$PROPS" | jq "."
|
||||
return
|
||||
}
|
||||
|
||||
# $1: message, $2: level, $3: operation, $4: code
|
||||
writeJournalLog() {
|
||||
PROGRAM_NAME="cfddns"
|
||||
DEFAULT_CODE=99
|
||||
DEFAULT_LEVEL="info"
|
||||
DEFAULT_MESSAGE="An unspecified error has occurred"
|
||||
DEFAULT_OPERATION="unspecified"
|
||||
|
||||
# translate error levels
|
||||
if [ -z "$2" ]; then
|
||||
LOG_LEVEL=1
|
||||
else
|
||||
case "$2" in
|
||||
"emergency" | "emerg")
|
||||
LOG_LEVEL=7
|
||||
;;
|
||||
"alert")
|
||||
LOG_LEVEL=6
|
||||
;;
|
||||
"critical" | "crit")
|
||||
LOG_LEVEL=5
|
||||
;;
|
||||
"error" | "err")
|
||||
LOG_LEVEL=4
|
||||
;;
|
||||
"warning" | "warn")
|
||||
LOG_LEVEL=3
|
||||
;;
|
||||
"notice")
|
||||
LOG_LEVEL=2
|
||||
;;
|
||||
"info")
|
||||
LOG_LEVEL=1
|
||||
;;
|
||||
"debug")
|
||||
LOG_LEVEL=0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# log the message
|
||||
if [ -z "$1" ]; then
|
||||
logger --journald <<end
|
||||
MESSAGE_ID=$(systemd-id128 new)
|
||||
SYSLOG_TIMESTAMP=$(getTimeStamp)
|
||||
SYSLOG_FACILITY=3
|
||||
SYSLOG_IDENTIFIER=${PROGRAM_NAME}
|
||||
PRIORITY=4
|
||||
ERRNO=${DEFAULT_CODE}
|
||||
OPERATION=${DEFAULT_OPERATION}
|
||||
MESSAGE=${DEFAULT_MESSAGE}
|
||||
end
|
||||
else
|
||||
logger --journald <<end
|
||||
MESSAGE_ID=$(systemd-id128 new)
|
||||
SYSLOG_TIMESTAMP=$(getTimeStamp)
|
||||
SYSLOG_FACILITY=3
|
||||
SYSLOG_IDENTIFIER=${PROGRAM_NAME}
|
||||
PRIORITY=${LOG_LEVEL}
|
||||
ERRNO=${4:-$DEFAULT_CODE}
|
||||
OPERATION=${3:-$DEFAULT_OPERATION}
|
||||
MESSAGE=$1
|
||||
end
|
||||
fi
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if [ "$1" = "json" ]; then
|
||||
writeJsonLog # this will generate a generic error message
|
||||
writeJsonLog "This is a test message" # generate this message at the default level with the default code
|
||||
writeJsonLog "This is a test message" "warning" # generate this message at the 'warning' level with the default code
|
||||
writeJsonLog "This is a test message" "error" "testing" # generate this message at the 'error' level, part of a 'test' operation, and with the default code
|
||||
writeJsonLog "This is a test message" "alert" "testing" 10 # generate this message at the 'alert' level with all parameters set
|
||||
elif [ "$1" = "journal" ]; then
|
||||
writeJournalLog # this will generate a generic error message
|
||||
writeJournalLog "This is a test message" # generate this message at the default level with the default code
|
||||
writeJournalLog "This is a test message" "warning" # generate this message at the 'warning' level with the default code
|
||||
writeJournalLog "This is a test message" "error" "testing" # generate this message at the 'error' level as part of a 'test' operation, and with the default code
|
||||
writeJournalLog "This is a test message" "alert" "testing" 10 # generate this message at the 'alert' level with all parameters set
|
||||
else
|
||||
printf "\nPlease specify either 'json' or 'journal' after the script name. Exiting.\n\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user