Skip to content

Commit

Permalink
add: ACME domain, .env generator; minor code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
LeKovr committed Jun 16, 2023
1 parent 03dcd0e commit 7754547
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.env
.env.*
*.done
90 changes: 59 additions & 31 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
# app custom Makefile

SHELL = /bin/sh
CFG =.env
CFG = .env

SOURCES ?= $(wildcard *.sql)
OBJECTS = $(SOURCES:.sql=.done)
OBJECTSDIRECT = $(SOURCES:.sql=.direct)

# ------------------------------------------------------------------------------
# шаблон файла .env
# app custom config
# comments prefixed with '#- ' will be copied to $(CFG).sample

define CONFIG_DEF
# dcape-dns config file, generated by make $(CFG)
#- Postgresql container name (access via docker)
PG_CONTAINER ?= dcape_db_1

# Postgresql container name (access via docker)
PG_CONTAINER=dcape_db_1
#- PowerDNS DB user name
PGUSER ?= pdns

# PowerDNS DB user name
PGUSER=pdns
#- PowerDNS DB name
PGDATABASE ?= pdns

# PowerDNS DB name
PGDATABASE=pdns
#- Used ONLY for direct DB access without docker (update-direct)
PGPASSWORD ?=

# Used ONLY for direct DB access without docker (start-direct)
PGPASSWORD=
#- ACME zone suffix
ACME_DOMAIN ?=

endef
export CONFIG_DEF
# ------------------------------------------------------------------------------

all: help

# ------------------------------------------------------------------------------

-include $(CFG)
export

Expand All @@ -38,41 +38,69 @@ export

start-hook: update

start-direct: update-direct

stop:

$(CFG): $(CFG).sample
@[ -f $@ ] || cp $< $@

# ------------------------------------------------------------------------------
## Usage
#:

## Load updated zone files via running PG container
update: $(OBJECTS)

%.done: %.sql
@echo "*** $< ***"
@csum=$$(md5sum $< | sed 's/ .*//') ; \
cat $< | docker exec -i $$PG_CONTAINER psql -U $$PGUSER -d $$PGDATABASE -vcsum=$$csum > $@

# ------------------------------------------------------------------------------
cat $< | docker exec -i $$PG_CONTAINER psql -U $$PGUSER -d $$PGDATABASE -vcsum=$$csum -vACME_DOMAIN=$(ACME_DOMAIN) > $@

## Load updated zone files via psql connection
update-direct: $(CFG) $(OBJECTSDIRECT)

%.direct: %.sql
@echo "*** $< ***"
@source $(CFG) && cat $< | PGPASSWORD=$$PGPASSWORD psql -h localhost -U $$PGUSER > $@

# ------------------------------------------------------------------------------

## Run psql via running PG container
psql:
@docker exec -it $$PG_CONTAINER psql -U $$PGUSER $$PGDATABASE

clean:
rm -rf *.done
# ------------------------------------------------------------------------------
## Other
#:

# This code generates $(CFG).sample from Makefile vars with previous comment line(s)
# See https://gist.github.com/LeKovr/2697fe02504d7c081b0bf79427c93db6

$(CFG).sample:
@echo "*** $@ ***"
@[ -f $@ ] || echo "$$CONFIG_DEF" > $@
# Internal: generate config sample data
.env.temp.mk:
@echo "define CFVAR" > $@
@grep -A 1 -h "^#- " $(MAKEFILE_LIST) | grep -vE "^--" \
| sed -E 's/^([^\n ]+)\ *\??=([^\n]*)$$/\1=$$(\1)\n/ ; s/^(#)-/\1/' >> $@
@echo "endef" >> $@

ifneq ($(findstring $(MAKECMDGOALS),config $(CFG).sample),)
include .env.temp.mk
endif

# Internal: generate config sample
$(CFG).sample: .env.temp.mk
@echo "# dcape-dns config file, generated by 'make config'\n" > $@
@echo "$$CFVAR" >> $@
@rm -f $<

## generate sample config
config: $(CFG).sample

# ------------------------------------------------------------------------------

## Remove .done files
clean:
rm -rf *.done

# This code handles group header and target comment with one or two lines only
## list Makefile targets
## (this is default target)
help:
@grep -A 1 -h "^## " $(MAKEFILE_LIST) \
| sed -E 's/^--$$// ; /./{H;$$!d} ; x ; s/^\n## ([^\n]+)\n(## (.+)\n)*(.+):(.*)$$/" " "\4" "\1" "\3"/' \
| sed -E 's/^" " "#" "(.+)" "(.*)"$$/"" "" "" ""\n"\1 \2" "" "" ""/' \
| xargs printf "%s\033[36m%-15s\033[0m %s %s\n"
9 changes: 7 additions & 2 deletions _lib.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/*
Вспомогательные функции
* FUNCTION soa_upd(a_old TEXT) RETURNS TEXT
* FUNCTION domain_id(a_name TEXT, a_type TEXT DEFAULT 'NATIVE') RETURNS INTEGER
* PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT)
*/

CREATE OR REPLACE FUNCTION soa_upd(a_old TEXT) RETURNS TEXT AS $_$
Expand Down Expand Up @@ -53,7 +58,7 @@ BEGIN
END
$_$ LANGUAGE plpgsql;

CREATE OR REPLACE PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT) LANGUAGE plpgsql AS $_$
CREATE OR REPLACE PROCEDURE acme_insert(a_domain_id INT, a_name TEXT, a_ip TEXT, a_ttl INT) AS $_$
/*
Добавление в зону для заданного a_ip записей для передачи ему контроля над зоной a_name.
Это используется в DNS-01 challenge ACME
Expand All @@ -70,4 +75,4 @@ BEGIN
FROM acme
;
END;
$_$;
$_$ LANGUAGE plpgsql;
60 changes: 60 additions & 0 deletions acme.sql.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Zone setup for DNS-01 ACME challenge

This code executed once per domain.
Future changes makes traefik via PowerDNS API
*/

-- This var must be set in psql args
SET vars.domain TO :'ACME_DOMAIN';

DO $_$
DECLARE
v_domain text := 'acme-' || current_setting('vars.domain'); -- domain name
v_ns text := 'ns.' || current_setting('vars.domain'); -- master DNS host
v_ns_admin text := 'admin.'|| current_setting('vars.domain'); -- master DNS admin email

v_refresh int := 10800;
v_retry int := 3600;
v_expire int := 604800;
v_ttl int := 1800;

v_domain_id integer; -- internal domain id
v_stamp text; -- zone timestamp
v_stamp_old text; -- previous zone SOA timestamp
v_soa text; -- zone SOA

BEGIN

IF v_domain = 'acme-' THEN
RAISE NOTICE 'ACME_DOMAIN is not set. Skipping acme zone setup';
RETURN;
END IF;

RAISE NOTICE 'Setup acme zone % for nameserver %',v_domain,v_ns;

SELECT INTO v_domain_id id FROM domains WHERE name = v_domain;
IF FOUND THEN
-- no any changes needed after creation
RAISE NOTICE 'Zone already exists. Skipping';
RETURN;
END IF;

INSERT INTO domains (name, type) VALUES
(v_domain, 'NATIVE')
RETURNING id INTO v_domain_id
;

INSERT INTO domainmetadata(domain_id, kind, content) VALUES
(v_domain_id, 'SOA-EDIT-API', 'INCREASE')
;

v_stamp := soa_upd();
v_soa := concat_ws(' ', v_ns, v_ns_admin, v_stamp, v_refresh, v_retry, v_expire, v_ttl);

INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES
(v_domain_id, v_domain, 60, 'SOA', 0, v_soa)
, (v_domain_id, v_domain, 1800, 'NS', 0, v_ns)
;
END;
$_$;
19 changes: 10 additions & 9 deletions domain.sql.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
DO $$

-- Reload PowerDNS zone data
/*
Complete PowerDNS zone records
*/

DO $_$
DECLARE
v_domain text := 'dev.lan'; -- domain name
v_ip text := '127.0.0.1'; -- base ip
Expand All @@ -13,6 +14,11 @@ DECLARE
v_stamp_old text; -- previous zone SOA timestamp
v_soa text; -- zone SOA

v_refresh int := 10800;
v_retry int := 3600;
v_expire int := 604800;
v_ttl int := 1800;

/*
refresh -- time lag until the slave again asks the master for a current version of the zone file
retry -- Should this request go unanswered, the “Retry” field regulates when a new attempt is to be carried out (< refresh)
Expand All @@ -22,11 +28,6 @@ DECLARE
Each value in seconds
*/

v_refresh int := 10800;
v_retry int := 3600;
v_expire int := 604800;
v_ttl int := 1800;

BEGIN
v_domain_id := domain_id(v_domain);

Expand All @@ -52,4 +53,4 @@ BEGIN
CALL acme_insert(v_domain_id, 'front.' || v_domain, v_ip1, v_ttl);

END;
$$;
$_$;

0 comments on commit 7754547

Please sign in to comment.