{"id":22374868,"url":"https://github.com/qubitproducts/dubber","last_synced_at":"2026-04-24T23:34:26.273Z","repository":{"id":48287582,"uuid":"86710432","full_name":"QubitProducts/dubber","owner":"QubitProducts","description":"Advanced DNS zone provisioning from orchestration services.","archived":false,"fork":false,"pushed_at":"2023-12-19T00:11:18.000Z","size":339,"stargazers_count":2,"open_issues_count":4,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-31T22:49:28.540Z","etag":null,"topics":["ceh","dns","gcloud","infra","kubernetes","marathon","route53"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QubitProducts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-30T14:13:28.000Z","updated_at":"2023-06-02T11:48:22.000Z","dependencies_parsed_at":"2024-06-20T12:03:24.420Z","dependency_job_id":null,"html_url":"https://github.com/QubitProducts/dubber","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QubitProducts%2Fdubber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QubitProducts%2Fdubber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QubitProducts%2Fdubber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QubitProducts%2Fdubber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QubitProducts","download_url":"https://codeload.github.com/QubitProducts/dubber/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245702463,"owners_count":20658620,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ceh","dns","gcloud","infra","kubernetes","marathon","route53"],"created_at":"2024-12-04T21:18:49.040Z","updated_at":"2026-04-24T23:34:26.248Z","avatar_url":"https://github.com/QubitProducts.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n*WARNING* dubber is in it's infancy. It may not even be a great idea at all.\n\n# Dubber\n\nA tool for provisioning DNS records based on dynamic config from\nvarious sources.\n\n## What Does Dubber Do?\n\nDubber queries various sources of information (currently Marathon,\nor Kubernetes) for the state of tasks and services running within\nthem.\n\nThis state is then passed to user supplied templates\n([text/template](https://godoc.org/text/template)\nwith [github.com/Masterminds/sprig](https://godoc.org/github.com/Masterminds/sprig)) enabled).\n\nOutput of the template is parsed as  RFC 1035 Zone file content using\n[github.com/miekg](https://godoc.org/github.com/miekg).\n\nThe resulting zone file is then passed to DNS provisioners (currently\nroute53 and gcloud DNS), which reconcile the provided zone\ncontent with the running zone.\n\nTemplate can use the comments on a DNS record to pass hints to the\nprovisioner.\n\nDubber will only delete records under the following two circumstances:\n- A record of the same Name, Class, RR Type and Grouping Flag values (see below), already\n  exists, and has a different value.\n- No records of the same Name, Class, RR Type and Grouping Flag values (see below), were\n  request, and all the flags mentioned in the ownerFlags in the provisioner configuration\n  are set, and match the configured regexp of each flag.\n\nSo by settings some grouping flag on a record, (e.g. route53.SetID), to a value that can be\nspecific to a given instance of dubber, you can then allow dubber to delete records that match\nthat specific value, if they are no longer needed.\n\n## Record Flags\n\nDubber uses DNS comments to translate into non-traditional DNS options supported by the provisioners.\nSome flags are used to group records so that conflicting records within a group can be remove/replaced,\nbut conflicting records in different groups are treated a separate entitied.\n\n### route53\n\n- `route53.SetID`: (Grouping Flag)  Associate these records with a Set\n- `route53.Weight`: Set a weight for the set\n- `route53.Alias`: \"HOSTEDZONEID:ALIASNAME\"\n- `route53.EvalTargetHealth`: \"true\" will enable target health evaluation\n\n### GCloud DNS\n\nTBD\n\n## An example\n\n```\ndiscoverers:\n  kubernetes:\n    - template: |\n      {{ $cluster := env `CLUSTER` }}\n      ; From Ingresses\n      {{- range $ing := .Ingresses }}\n        {{- $setID := or (index $ing.ObjectMeta.Labels `route53SetId`) $cluster }}\n        {{- $weight := or (index $ing.ObjectMeta.Labels `route53Weight`) `0` }}\n        {{- if len $ing.Status.LoadBalancer.Ingress }}\n        {{-   $sing := index $ing.Status.LoadBalancer.Ingress 0 }}\n        {{-   range $rule := $ing.Spec.Rules }}\n        {{-     if $rule.Host }}\n        {{-       if $sing.IP }}\n      {{ $rule.Host }} 60 A {{$sing.IP}}; route53.SetID={{ $setID }} route53.Weight={{ $weight }}\n        {{-       else }}\n      {{ $rule.Host }} CNAME {{ $sing.Hostname }};\n        {{-       end }}\n        {{-     end }}\n        {{-   end }}\n        {{- end  }}\n      {{- end }}\n  marathon:\n    - endpoints:\n      -  http://marathon.mesos.example.com/api\n      template: |\n        {{- $publicLB := `Z1234:dualstack.exanple-public.elb.amazonaws.com.`}}\n        {{- $privateLB := `Z1234:dualstack.exanple-private.elb.amazonaws.com.`}}\n        {{- range .Applications }}\n        {{-   if (index .Labels `dnsName`) }}\n        {{-     if eq (index .Labels `externalAccess`) `public` }}\n        {{ index .Labels `dnsName`}} 0 A 0.0.0.0 ; route53.Alias={{$publicLB}}\n        {{-     else }}\n        {{ index .Labels `dnsName`}} 0 A 0.0.0.0 ; route53.Alias={{$privateLB}}\n        {{-     end }}\n        {{-   end }}\n        {{- end }}\n\nprovisioners:\n  route53:\n    - zone: example.com.\n      zoneid: Z56789\n      ownerFlags:\n        \"route53.SetID\": \"{{ env `CLUSTER` }}\"\n```\n\nWill create a route53 alias record, based on the dnsName and externalAccess\nlabels on a Marathon task.\n\nDifferent disoveres can provide different data, and any number of records can be\ncreated for different elements.\n\n# TODO\n- Watch rather than poll\n- Possibly unify all data and pass it to a single template, rather than each\n  discoverer having it's own template.\n- Template functions to help build the records.\n- Purging - possibly track the state of the records and allow purging of anything\n  we created (this is somewhat achievable via the ownerFlags)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubitproducts%2Fdubber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqubitproducts%2Fdubber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubitproducts%2Fdubber/lists"}