Skip to content

Commit

Permalink
First ddns approach (#100)
Browse files Browse the repository at this point in the history
* First ddns approach

* Add a condition to skip nsupdate when not needed

* set TTL to 600

* Repair NS entries if they don't match AWS'

* Add retries with random delay to route53 task


* Add env variable for ddns TTL

---------

Co-authored-by: Guillaume Coré <gucore@redhat.com>
  • Loading branch information
agonzalezrh and fridim authored Dec 4, 2024
1 parent ba947f6 commit c029557
Show file tree
Hide file tree
Showing 17 changed files with 155 additions and 20 deletions.
13 changes: 13 additions & 0 deletions conan/conan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,17 @@ workdir=${workdir:-~/pool_management}
# Vault file
vault_file=${vault_file:-~/secrets/infra-sandbox-vault}

# Dynamic DNS
ddns_server=${ddns_server:-"ipaserver"}
ddns_key_name=${ddns_key_name:-mydynamickey}
ddns_key_algorithm=${ddns_key_algorithm:-"hmac-sha512"}
ddns_key_secret=${ddns_key_secret:-}
ddns_ttl=${ddns_ttl:-600}

# Pattern to filter the sandboxes to cleanup
sandbox_filter=${sandbox_filter:-}


# Lock timeout: the number of hours after which a lock on a sandbox expires.
# For ex: '2': a conan process will have 2h to cleanup the sandbox before another
# process can claim the sandbox for cleanup.
Expand All @@ -73,6 +81,11 @@ export conan_instance
export dynamodb_profile
export dynamodb_region
export dynamodb_table
export ddns_server
export ddns_key_name
export ddns_key_algorithm
export ddns_key_secret
export ddns_ttl
export lock_timeout
export max_retries
export aws_nuke_retries
Expand Down
4 changes: 1 addition & 3 deletions conan/quick_install_rhel.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
sudo adduser opentlc-mgr

sudo dnf install -y vim git wget rush kerberos krb5-workstation ipa-client python3-pip
sudo dnf install -y vim git wget rush python3-pip

sudo -u opentlc-mgr mkdir -p -m 700 \
~opentlc-mgr/.aws/ \
Expand All @@ -25,8 +25,6 @@ sudo -u opentlc-mgr git clone https://github.com/rhpds/sandbox.git ~opentlc-mgr/
sudo -u opentlc-mgr ln -s ~opentlc-mgr/pool_management/sandbox/ ~opentlc-mgr/pool_management/aws-sandbox

echo "Edit ~opentlc-mgr/.aws/credentials"
echo "Setup IPA access (ipa-client-install)"
echo "copy secret: hostadmin.keytab into ~opentlc-mgr/secrets/"
echo "copy secret: infra-sandbox-vault into ~opentlc-mgr/secrets/"

sudo cp ~opentlc-mgr/pool_management/sandbox/conan/conan.service /etc/systemd/system/
Expand Down
3 changes: 3 additions & 0 deletions conan/readme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ $ podman run \
-e conan_instance=container$$ \
-e AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws_credentials \
-e vault_file=/run/secrets/vault_file \
-e ddns_server="..." \
-e ddns_key_name="..." \
-e ddns_key_secret="...." \
-e workdir=/home/opentlc-mgr/pool_management \
-e AWSCLI=aws \
-e threads=1 \
Expand Down
5 changes: 0 additions & 5 deletions conan/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ dnspython
docutils
gssapi
importlib-resources
ipa
ipaclient
ipalib
ipaplatform
ipapython
Jinja2
jmespath
MarkupSafe
Expand Down
9 changes: 8 additions & 1 deletion conan/wipe_sandbox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ debug=${debug:-false}
: "${aws_profile:?"aws_profile is unset or empty"}"
: "${aws_nuke_binary_path:?"aws_nuke_binary_path is unset or empty"}"
: "${lock_timeout:?"lock_timeout is unset or empty"}"
: "${ddns_server:?"ddns_server is unset or empty"}"
: "${ddns_key_name:?"ddns_key_name is unset or empty"}"
: "${ddns_key_secret:?"ddns_key_secret is unset or empty"}"
: "${vault_file:?"vault_file is unset or empty"}"
: "${workdir:?"workdir is unset or empty"}"

Expand Down Expand Up @@ -223,7 +226,6 @@ sandbox_reset() {
ANSIBLE_PYTHON_INTERPRETER=$(which python3)
export ANSIBLE_PYTHON_INTERPRETER
fi

if ansible-playbook -i localhost, \
-e _account_num="${s}" \
-e aws_master_profile="${aws_profile}" \
Expand All @@ -235,6 +237,11 @@ sandbox_reset() {
-e output_dir="${workdir}/output_dir_sandbox" \
-e vault_file="${vault_file}" \
-e aws_cli="${AWSCLI}" \
-e ddns_key_algorithm="${ddns_key_algorithm}" \
-e ddns_server="${ddns_server}" \
-e ddns_key_name="${ddns_key_name}" \
-e ddns_key_secret="${ddns_key_secret}" \
-e ddns_ttl="${ddns_ttl}" \
-e run_aws_nuke_legacy="${run_aws_nuke_legacy:-false}" \
reset_single.yml > "${logfile}"; then
echo "$(date -uIs) ${sandbox} reset OK"
Expand Down
24 changes: 24 additions & 0 deletions deploy/helm-conan/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,33 @@ spec:
- name: vault_file
value: /secrets/vault_file/vault_file

- name: ddns_server
valueFrom:
secretKeyRef:
name: {{ .Values.sandbox_conan_secrets.ddns.server }}
key: server

- name: ddns_key_name
valueFrom:
secretKeyRef:
name: {{ .Values.sandbox_conan_secrets.ddns.key_name }}
key: key_name

- name: workdir
value: /home/opentlc-mgr/pool_management

- name: ddns_key_secret
valueFrom:
secretKeyRef:
name: {{ .Values.sandbox_conan_secrets.ddns.key_secret }}
key: key_secret

- name: ddns_key_algorithm
valueFrom:
secretKeyRef:
name: {{ .Values.sandbox_conan_secrets.ddns.key_algorithm }}
key: key_algorithm

- name: AWSCLI
value: {{ .Values.awscli | default "aws" | quote }}

Expand Down
21 changes: 21 additions & 0 deletions deploy/helm-conan/templates/secrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ data:
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.sandbox_conan_secrets.ddns.name }}
namespace: {{ .Values.sandbox_conan_secrets.ddns.namespace | default .Values.namespace }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/version: {{ .Chart.Version | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
meta.helm.sh/release-name: {{ .Release.Name }}
meta.helm.sh/release-namespace: {{ .Release.Namespace }}
{{- if .Values.labels }}
{{- toYaml .Values.labels | nindent 4 }}
{{- end }}
type: Opaque
data:
server: {{ .Values.sandbox_conan_secrets.ddns.key_server | b64enc | quote }}
key_name: {{ .Values.sandbox_conan_secrets.ddns.key_name | b64enc | quote }}
key_algorithm: {{ .Values.sandbox_conan_secrets.ddns.key_algorithm | b64enc | quote }}
key_secret: {{ .Values.sandbox_conan_secrets.ddns.key_secret | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.sandbox_conan_secrets.vault_secret.name }}
namespace: {{ .Values.sandbox_conan_secrets.vault_secret.namespace | default .Values.namespace }}
Expand Down
7 changes: 7 additions & 0 deletions deploy/helm-conan/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ sandbox_conan_secrets:
name: vault-file
#content: "..."

ddns:
#namespace: ...
name: ipa4
server: ipaserver
key_name: "mydynamickey"
key_algorithm: "hmac-sha512"
#key_secret: "..."
aws_credentials:
#namespace: ...
name: aws-credentials
Expand Down
3 changes: 3 additions & 0 deletions playbooks/create_range.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@
account_email: sandbox{{account_num}}@opentlc.com
account_destination_ou: sandboxes
output_dir: ~/pool_management/output_dir_sandbox
ddns_server: ipaserver
ddns_key_name: mydynamickey
ddns_key_algorithm: hmac-sha512
operation: CREATE
3 changes: 2 additions & 1 deletion playbooks/readme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ sandbox-list -all --sort name |tail
(python_virtualenv) [opentlc-mgr@admin (PROD) ~]$ cd pool_management/sandbox/playbooks
# .create 10 AWS sandbox accounts: sandbox3001 .. sandbox3010
./create_range.yml -e account_num_start=3001 -e account_count=10
# You can use 'IPA opentlc.com hostadmin for conan' for the kerberos creds
./create_range.yml -e account_num_start=3001 -e account_count=10 -e ddns_key_name=... -e ddns_key_secret=... -e ddns_server=...
# Add GOLD IMAGES to the new accounts
# Generate the list of new sandboxes
Expand Down
3 changes: 3 additions & 0 deletions playbooks/reset_single.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@
account_email: sandbox{{_account_num}}@opentlc.com
account_destination_ou: sandboxes
output_dir: ~/pool_management/output_dir_sandbox
ddns_server: ipaserver
ddns_key_name: mydynamickey
ddns_key_algorithm: hmac-sha512
operation: RESET
8 changes: 7 additions & 1 deletion playbooks/roles/infra-aws-sandbox/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ ansible localhost \
ansible -i admin-dev, admin-dev \
-m include_role -a "name=infra-aws-sandbox" \
-e ansible_user=gucore-redhat.com \
-e ddns_server=ipaserver \
-e ddns_key_name=mydynamickey \
-e ddns_key_secret=... \
-e aws_master_profile=pool-manager-admin \
-e account_name=sandbox2 \
-e account_email=sandbox2@opentlc.com \
Expand All @@ -31,7 +34,7 @@ ansible -i admin-dev, admin-dev \
.Example with playbook, create_all.yml
[source,yaml]
----
# ansible-playbook -i admin-dev, -e @~/secrets/ipa.yml create_all.yml
# ansible-playbook -i admin-dev, -e @~/secrets/ddns.yml create_all.yml
- hosts: all
gather_facts: no
run_once: yes
Expand All @@ -56,6 +59,9 @@ ansible -i admin-dev, admin-dev \
ansible -i admin-dev, admin-dev \
-m include_role -a "name=infra-aws-sandbox" \
-e ansible_user=gucore-redhat.com \
-e ddns_server=ipaserver \
-e ddns_key_name=mydynamickey \
-e ddns_key_secret=... \
-e aws_master_profile=pool-manager-admin \
-e account_name=sandbox2 \
-e account_email=sandbox2@opentlc.com \
Expand Down
7 changes: 5 additions & 2 deletions playbooks/roles/infra-aws-sandbox/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ vault_file: ~/secrets/infra-sandbox-vault
subdomain_base: .opentlc.com
output_dir: '/tmp/output_dir'

kerberos_realm: OPENTLC.COM
ipa_domain: opentlc.com
ddns_key_name: mydynamickey
ddns_key_algorithm: hmac-sha512
ddns_port: 53
ddns_domain: opentlc.com
ddns_server: ipaserver

# yamllint disable-line rule:line-length
opentlc_admin_backdoor: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvZvn+GL0wTOsAdh1ikIQoqj2Fw/RA6F14O347rgKdpkgOQpGQk1k2gM8wcla2Y1o0bPIzwlNy1oh5o9uNjZDMeDcEXWuXbu0cRBy4pVRhh8a8zAZfssnqoXHHLyPyHWpdTmgIhr0UIGYrzHrnySAnUcDp3gJuE46UEBtrlyv94cVvZf+EZUTaZ+2KjTRLoNryCn7vKoGHQBooYg1DeHLcLSRWEADUo+bP0y64+X/XTMZOAXbf8kTXocqAgfl/usbYdfLOgwU6zWuj8vxzAKuMEXS1AJSp5aeqRKlbbw40IkTmLoQIgJdb2Zt98BH/xHDe9xxhscUCfWeS37XLp75J
Expand Down
37 changes: 37 additions & 0 deletions playbooks/roles/infra-aws-sandbox/tasks/ddns.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
- tags:
- nuke
- ddns
when: operation in ['CREATE','RESET'] or nuke_sandbox | bool
block:
- name: Fetch all NS records for this sandbox
shell: >-
set -o pipefail;
host -t ns -W 60 -R 10 {{ account_name }}.{{ ddns_domain }}
| awk '{ print $4 }'
register: _recordfind
ignore_errors: true
changed_when: false

- when: _recordfind is succeeded
set_fact:
ddns_ns_records: "{{ _recordfind.stdout.split('\n') }}"

- when: _recordfind is failed
set_fact:
ddns_ns_records: ""

- name: Override NS records to DDNS
when: ddns_ns_records | sort != ns_records | sort
community.general.nsupdate:
state: present
server: "{{ lookup('dig', ddns_server) }}"
key_name: "{{ ddns_key_name }}"
key_algorithm: "{{ ddns_key_algorithm | d('hmac-sha512') }}"
key_secret: "{{ ddns_key_secret }}"
port: "{{ ddns_port | d('53') }}"
type: NS
ttl: "{{ ddns_ttl | default(600, true) }}"
zone: "{{ ddns_domain }}."
record: "{{ account_name }}.{{ ddns_domain }}."
value: "{{ ns_records }}"
6 changes: 6 additions & 0 deletions playbooks/roles/infra-aws-sandbox/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@
- include_tasks: keypair.yml
when: operation in ['CREATE', 'RESET']
tags: keypair
- include_tasks: ddns.yml
tags: ddns
when:
- ddns_server is defined
- ddns_key_name is defined
- ddns_key_secret is defined
- import_tasks: pool.yml
1 change: 0 additions & 1 deletion playbooks/roles/infra-aws-sandbox/tasks/pre_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
path: "{{ output_dir }}"
state: directory


- name: Ensure vault file exists
stat:
path: "{{ vault_file }}"
Expand Down
21 changes: 15 additions & 6 deletions playbooks/roles/infra-aws-sandbox/tasks/route53.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,22 @@

- name: Save NS records
set_fact:
ns_records: "{{ _route53facts.DelegationSet.NameServers }}"
ns_records: >-
{{ _route53facts.DelegationSet.NameServers
| map('regex_replace', '$', '.') }}
- name: Generate commands to del NS records to IPA
copy:
content: |-
ipa dnsrecord-del opentlc.com. {{ account_name }}
dest: "{{ output_dir }}/ipa_del_{{ account_name }}.sh"
- name: Set the NS records using the Delegation Set
route53:
state: present
zone: "{{ account_name }}{{subdomain_base}}."
record: "{{ account_name }}{{subdomain_base}}."
type: NS
value: "{{ ns_records }}"
overwrite: true
register: _route53zoneNS
retries: 5
delay: "{{ 60|random(start=3, step=1) }}"
until: _route53zoneNS is succeeded

- name: Add HostedZoneId to the report
lineinfile:
Expand Down

0 comments on commit c029557

Please sign in to comment.