Compare commits

...

7 Commits

Author SHA1 Message Date
IamTheFij 66efa5e17c Add repo links to README.md
continuous-integration/drone/push Build is passing Details
Should make it easier to finds the original source.
2020-02-22 07:52:16 -08:00
IamTheFij d6c46b5c10 README.md update to describe new contents
continuous-integration/drone/push Build is passing Details
Explains that this repo does not actually have any code and it merely
is an image wrapping an existing example script
2020-01-21 18:10:16 -08:00
IamTheFij 356071570a update drone pipelines for new Dockerfile
continuous-integration/drone/push Build is passing Details
2020-01-21 18:00:35 -08:00
IamTheFij 6ac78cbe89 Stop copying extra qemu files
continuous-integration/drone/push Build is passing Details
2020-01-21 17:52:45 -08:00
IamTheFij b11d6f6d88 WIP: Get started squashing things down 2020-01-21 17:46:39 -08:00
IamTheFij de8cf7aab8 WIP: Get started squashing things down 2020-01-21 17:44:02 -08:00
IamTheFij fea176f7f3 Update upstream example script 2020-01-21 17:29:05 -08:00
8 changed files with 43 additions and 225 deletions

View File

@ -2,18 +2,6 @@ kind: pipeline
name: linux-amd64 name: linux-amd64
steps: steps:
- name: get qemu
image: ubuntu:bionic
commands:
- apt-get update
- apt-get install -y make wget
- make build/qemu-x86_64-static
when:
branch:
- master
event:
- push
- tag
- name: build - name: build
image: plugins/docker image: plugins/docker
@ -37,18 +25,6 @@ kind: pipeline
name: linux-arm name: linux-arm
steps: steps:
- name: get qemu
image: ubuntu:bionic
commands:
- apt-get update
- apt-get install -y make wget
- make build/qemu-arm-static
when:
branch:
- master
event:
- push
- tag
- name: build - name: build
image: plugins/docker image: plugins/docker
@ -75,18 +51,6 @@ kind: pipeline
name: linux-arm64 name: linux-arm64
steps: steps:
- name: get qemu
image: ubuntu:bionic
commands:
- apt-get update
- apt-get install -y make wget
- make build/qemu-aarch64-static
when:
branch:
- master
event:
- push
- tag
- name: build - name: build
image: plugins/docker image: plugins/docker

View File

@ -1,21 +1,27 @@
ARG REPO=library ARG REPO=library
FROM multiarch/qemu-user-static:4.1.0-1 as qemu-user-static
# Make sure a dummy x86_64 file exists so that the copy command doesn't error
RUN touch /usr/bin/qemu-x86_64-fake
FROM ${REPO}/python:3-alpine FROM ${REPO}/python:3-alpine
# Copy mutliarch file to run builds on x86_64
ARG ARCH=x86_64 ARG ARCH=x86_64
COPY ./build/qemu-${ARCH}-static /usr/bin/ COPY --from=qemu-user-static /usr/bin/qemu-${ARCH}-* /usr/bin/
RUN mkdir -p /src RUN mkdir -p /src
WORKDIR /src WORKDIR /src
COPY ./requirements.txt ./ # Get Cloudflare example script
RUN pip install -r ./requirements.txt ENV CF_VERSION=2.6.0
ADD https://raw.githubusercontent.com/cloudflare/python-cloudflare/$CF_VERSION/examples/example_update_dynamic_dns.py ./update_ddns.py
RUN chmod +x ./update_ddns.py
COPY ./start.sh ./ RUN pip install cloudflare==$CF_VERSION
COPY ./update_ddns.py ./update_ddns.py
ENV DOMAIN="" ENV DOMAIN=""
USER nobody USER nobody
CMD [ "/src/start.sh" ] ENTRYPOINT [ "/src/update_ddns.py" ]

View File

@ -1,4 +1,5 @@
DOCKER_TAG ?= cloudflare-ddns-dev-${USER} DOCKER_TAG ?= cloudflare-ddns-dev-${USER}
.PHONY: clean
.PHONY: default .PHONY: default
default: test default: test
@ -7,35 +8,25 @@ default: test
test: test:
@echo ok @echo ok
.PHONY: update
update:
curl -o update_ddns.py https://raw.githubusercontent.com/cloudflare/python-cloudflare/master/examples/example_update_dynamic_dns.py
chmod +x update_ddns.py
.PHONY: build .PHONY: build
build: build/qemu-x86_64-static build:
docker build . -t ${DOCKER_TAG} docker build . -t ${DOCKER_TAG}
build/qemu-arm-static:
./get_qemu.sh arm
build/qemu-x86_64-static:
./get_qemu.sh x86_64
build/qemu-aarch64-static:
./get_qemu.sh aarch64
.PHONY: cross-build-arm .PHONY: cross-build-arm
cross-build-arm: build/qemu-arm-static cross-build-arm:
docker build --build-arg REPO=arm32v6 --build-arg ARCH=arm . -t ${DOCKER_TAG}-linux-arm docker build --build-arg REPO=arm32v6 --build-arg ARCH=arm . -t ${DOCKER_TAG}-linux-arm
.PHONY: cross-build-arm64 .PHONY: cross-build-arm64
cross-build-arm64: build/qemu-aarch64-static cross-build-arm64:
docker build --build-arg REPO=arm64v8 --build-arg ARCH=aarch64 . -t ${DOCKER_TAG}-linux-arm64 docker build --build-arg REPO=arm64v8 --build-arg ARCH=aarch64 . -t ${DOCKER_TAG}-linux-arm64
.PHONY: all
all: build cross-build-arm cross-build-arm64
.PHONY: run .PHONY: run
run: build run: build
docker run --rm -e DOMAIN=${DOMAIN} \ docker run --rm \
-e CF_API_EMAIL=${CF_API_EMAIL} \ -e CF_API_EMAIL=${CF_API_EMAIL} \
-e CF_API_KEY=${CF_API_KEY} \ -e CF_API_KEY=${CF_API_KEY} \
${DOCKER_TAG} ${DOCKER_TAG} \
"${DOMAIN}"

View File

@ -1,21 +1,34 @@
# Docker Cloudfare DDNS # Docker Cloudfare DDNS
Simple Docker image to dynamically update a Cloudflare DNS record. Simple Docker image that wraps an example script to dynamically update a Cloudflare DNS record.
## Usage ## Usage
All parameters are passed to the script using env variables, so export the following: There are two things to configure. First, the domain that you wish to update needs to be provided as a command line argument. This can be done by adding it to the end of your run command (example in the Makefile) or by adding it as a command to your compose file. Eg:
DOMAIN=sub.example.com ddns:
CF_API_EMAIL=admin@example.com image: IamTheFij/cloudflare-ddns
command: ["example.com"]
Your Cloudflare credentials can be passed in any way that [python-cloudflare](https://github.com/cloudflare/python-cloudflare) allows. Generally, either via envioronment variables:
CF_API_EMAIL=admin@example.com # Do not set if using an API Token
CF_API_KEY=00000000000000000000 CF_API_KEY=00000000000000000000
CF_API_CERTKEY='v1.0-...'
Or by providing a file mounted to the working directory in the image, `/src/.cloudflare.cfg` that contains something like:
[CloudFlare]
emal = admin@example.com # Do not set if using an API Token
token = 00000000000000000000
certtoken = v1.0-...
Then run. To execute from this directory, you can use the convenient Make target. Then run. To execute from this directory, you can use the convenient Make target.
make run make run
## Development ## Source
The script is straight from the examples provided by Cloudflare on their Github. The latest version can be downloaded using: Original source: https://git.iamthefij.com/iamthefij/docker-cloudflare-ddns
make update Github mirror: https://github.com/iamthefij/docker-cloudflare-ddns

View File

@ -1,13 +0,0 @@
#! /bin/bash
HOST_ARCH=x86_64
VERSION=v2.9.1-1
mkdir -p build
cd build
for target_arch in $*; do
wget -N https://github.com/multiarch/qemu-user-static/releases/download/$VERSION/${HOST_ARCH}_qemu-${target_arch}-static.tar.gz
tar -xvf ${HOST_ARCH}_qemu-${target_arch}-static.tar.gz
rm ${HOST_ARCH}_qemu-${target_arch}-static.tar.gz
done

View File

@ -1 +0,0 @@
cloudflare

View File

@ -1,3 +0,0 @@
#! /bin/sh
exec /src/update_ddns.py $DOMAIN

View File

@ -1,139 +0,0 @@
#!/usr/bin/env python
"""Cloudflare API code - example"""
from __future__ import print_function
import os
import sys
import re
import json
import requests
sys.path.insert(0, os.path.abspath('..'))
import CloudFlare
def my_ip_address():
"""Cloudflare API code - example"""
# This list is adjustable - plus some v6 enabled services are needed
# url = 'http://myip.dnsomatic.com'
# url = 'http://www.trackip.net/ip'
# url = 'http://myexternalip.com/raw'
url = 'https://api.ipify.org'
try:
ip_address = requests.get(url).text
except:
exit('%s: failed' % (url))
if ip_address == '':
exit('%s: failed' % (url))
if ':' in ip_address:
ip_address_type = 'AAAA'
else:
ip_address_type = 'A'
return ip_address, ip_address_type
def do_dns_update(cf, zone_name, zone_id, dns_name, ip_address, ip_address_type):
"""Cloudflare API code - example"""
try:
params = {'name':dns_name, 'match':'all', 'type':ip_address_type}
dns_records = cf.zones.dns_records.get(zone_id, params=params)
except CloudFlare.exceptions.CloudFlareAPIError as e:
exit('/zones/dns_records %s - %d %s - api call failed' % (dns_name, e, e))
updated = False
# update the record - unless it's already correct
for dns_record in dns_records:
old_ip_address = dns_record['content']
old_ip_address_type = dns_record['type']
if ip_address_type not in ['A', 'AAAA']:
# we only deal with A / AAAA records
continue
if ip_address_type != old_ip_address_type:
# only update the correct address type (A or AAAA)
# we don't see this becuase of the search params above
print('IGNORED: %s %s ; wrong address family' % (dns_name, old_ip_address))
continue
if ip_address == old_ip_address:
print('UNCHANGED: %s %s' % (dns_name, ip_address))
updated = True
continue
# Yes, we need to update this record - we know it's the same address type
dns_record_id = dns_record['id']
dns_record = {
'name':dns_name,
'type':ip_address_type,
'content':ip_address
}
try:
dns_record = cf.zones.dns_records.put(zone_id, dns_record_id, data=dns_record)
except CloudFlare.exceptions.CloudFlareAPIError as e:
exit('/zones.dns_records.put %s - %d %s - api call failed' % (dns_name, e, e))
print('UPDATED: %s %s -> %s' % (dns_name, old_ip_address, ip_address))
updated = True
if updated:
return
# no exsiting dns record to update - so create dns record
dns_record = {
'name':dns_name,
'type':ip_address_type,
'content':ip_address
}
try:
dns_record = cf.zones.dns_records.post(zone_id, data=dns_record)
except CloudFlare.exceptions.CloudFlareAPIError as e:
exit('/zones.dns_records.post %s - %d %s - api call failed' % (dns_name, e, e))
print('CREATED: %s %s' % (dns_name, ip_address))
def main():
"""Cloudflare API code - example"""
try:
dns_name = sys.argv[1]
except IndexError:
exit('usage: example-update-dynamic-dns.py fqdn-hostname')
host_name, zone_name = dns_name.split('.', 1)
ip_address, ip_address_type = my_ip_address()
print('MY IP: %s %s' % (dns_name, ip_address))
cf = CloudFlare.CloudFlare()
# grab the zone identifier
try:
params = {'name':zone_name}
zones = cf.zones.get(params=params)
except CloudFlare.exceptions.CloudFlareAPIError as e:
exit('/zones %d %s - api call failed' % (e, e))
except Exception as e:
exit('/zones.get - %s - api call failed' % (e))
if len(zones) == 0:
exit('/zones.get - %s - zone not found' % (zone_name))
if len(zones) != 1:
exit('/zones.get - %s - api call returned %d items' % (zone_name, len(zones)))
zone = zones[0]
zone_name = zone['name']
zone_id = zone['id']
do_dns_update(cf, zone_name, zone_id, dns_name, ip_address, ip_address_type)
exit(0)
if __name__ == '__main__':
main()