{"id":20946110,"url":"https://github.com/raamsri/dops","last_synced_at":"2025-06-18T11:40:03.738Z","repository":{"id":235441542,"uuid":"451834319","full_name":"raamsri/dops","owner":"raamsri","description":"Multi-Cloud DNS Operations","archived":false,"fork":false,"pushed_at":"2024-07-19T04:14:23.000Z","size":85,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-13T04:27:58.832Z","etag":null,"topics":["dns","dns-records","multicloud"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raamsri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-01-25T10:35:21.000Z","updated_at":"2024-04-23T08:50:14.000Z","dependencies_parsed_at":"2024-05-06T05:28:27.830Z","dependency_job_id":"92ba0d1a-4aaa-41d6-ba12-ea51a65f1da4","html_url":"https://github.com/raamsri/dops","commit_stats":null,"previous_names":["raamsri/dops"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/raamsri/dops","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raamsri%2Fdops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raamsri%2Fdops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raamsri%2Fdops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raamsri%2Fdops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raamsri","download_url":"https://codeload.github.com/raamsri/dops/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raamsri%2Fdops/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260546249,"owners_count":23025903,"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":["dns","dns-records","multicloud"],"created_at":"2024-11-18T23:52:01.433Z","updated_at":"2025-06-18T11:39:58.728Z","avatar_url":"https://github.com/raamsri.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dops [DNS Operations]\n\n**`dops`** manages DNS operations on a cloud provider to synchronize the needed hostname-target values(records) from multiple sources.\n\n**Note:** `dops` is *NOT* a DNS server\n\n## Providers\n\nA `provider` is a cloud service provider with supported DNS web service like DNS registration and routing. This is where the DNS records are operated. Currently, supported providers are:\n\n1. `aws` - AWS Route53\n2. `cloudflare` - Cloudflare\n3. `inmemory` - Emulates a provider for testing\n\nMore providers can be individually added when required by implementing the `provider.Provider{}` interface methods.\n\n## Sources\n\nA `source` provides the list of DNS records(*endpoints*) that must be created/synchronised with a suported `provider`.\n\nSupported sources:\n\n1. `connector` - This is a TCP connection source backed by *Go* native *gob* decoding. This is a super convenient approach for any other Go program to transmit DNS records via `net.Listen(\"tcp\", \":xxxx\")`. After the connection is established, `dops` reconciliation loop will query the *listening* source for endpoints periodically. This design makes `dops` *pluggable* with another internal service.\n\n2. `dummy` - emulates a source by providing randomly generated endpoints for testing.\n\n3. `empty` - An empty source provides no endpoint; a quick cleanup tool for testing.\n\nMore sources can be individually added when required by implementing the `source.Source{}` interface methods.\n\n## Ownership\n\nMultiple instances of `dops` with different filters/parameteres can be operated on a specific or a set of hosted zones. To facilitate harmonious co-operation, for each endpoint dops injects a TXT record with ownership labels pertaining to the running instance that operates that set of records.\n\nUnlike `A` type records, `CNAME` records cannot share hostname with any other type(A, TXT, SRV, etc.) To circumvent this limitation, TXT records are maintained with the user provided prefix. **This is transparently handled, users need not fret**.\n\nFor example:\n\nA source endpoint with hostname **try** for domain **dops2.toppr.systems** of type `A` record will create two entries in the provider's DNS hosted zone. Note that the hostnames are same for both type of records.\n\n\u003e pvsb.dops2.toppr.systems\n\u003e\u003e Actual record -\u003e `try.dops2.toppr.systems 0 IN A  192.0.2.252`\n\u003e\u003e\n\u003e\u003eOwnership record -\u003e `try.dops2.toppr.systems 0 IN TXT  \\\"origin=dops,dops/owner=test\\\"`\n\nHowever, the same endpoint of record type `CNAME` will have an ownership record with a different hostname with prefix.\n\n\u003e pvsb.dops2.toppr.systems\n\u003e\u003e Actual record -\u003e `try.dops2.toppr.systems 0 IN CNAME ip-10-1-0-80.ap-south-1.compute.internal`\n\u003e\u003e\n\u003e\u003eOwnership record -\u003e `prefix-try.dops2.toppr.systems 0 IN TXT  \\\"origin=dops,dops/owner=test\\\"`\n\nIt's not recommended to manually modify dops managed records on the cloud portal, it will leave records in an inconsistent state while synchronising.\n\n## CLI\n\n`dops` takes parameters in effectively two forms - command flags and env variables. Both can be mixed. Parameters marked as *required* are mandatory.\n\nMore information is available with `dops --help`\n\n```bash\n$ dops --source=dummy \\\n--provider=aws \\\n--fqdn-template=\"dops2.toppr.systems\" \\\n--txt-owner-id=test \\\n--aws-zone-type=private \\\n--aws-zones-cache-duration=2h \\\n--domain-filter=\"dops2.toppr.systems\" \\\n--domain-filter=\"dops.toppr.systems\" \\\n--log-format=json \\\n--log-level=info\n\nINFO[0000] config: {DefaultTargets:[] Sources:[dummy] FQDNTemplate:dops2.toppr.systems PublishHostIP:false ConnectorSourceServer:localhost:9876 Provider:aws DomainFilter:[dops2.toppr.systems dops.toppr.systems] ExcludeDomains:[] RegexDomainFilter: RegexDomainExclusion: ZoneIDFilter:[] AWSZoneType:private AWSZoneTagFilter:[] AWSAssumeRole: AWSBatchChangeSize:1000 AWSBatchChangeInterval:1s AWSEvaluateTargetHealth:true AWSAPIRetries:3 AWSPreferCNAME:true AWSZoneCacheDuration:2h0m0s CloudflareProxied:false CloudflareZonesPerPage:50 InMemoryZones:[] Policy:sync Registry:txt TXTOwnerID:test TXTPrefix: TXTSuffix: Interval:1m0s MinEventSyncInterval:5s Once:false DryRun:false UpdateEvents:false LogFormat:json MetricsAddress::7979 LogLevel:info TXTCacheInterval:0s TXTWildcardReplacement: ManagedDNSRecordTypes:[A CNAME]}\n\n\n{\"level\":\"info\",\"msg\":\"Applying provider record filter for domains: [dops2.toppr.systems. .dops2.toppr.systems. dops.toppr.systems. .dops.toppr.systems.]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-ccod.dops2.toppr.systems A [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-ccod.dops2.toppr.systems TXT [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-cdzs.dops2.toppr.systems A [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-cdzs.dops2.toppr.systems TXT [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-gusp.dops2.toppr.systems A [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-gusp.dops2.toppr.systems TXT [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-gyac.dops2.toppr.systems A [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-gyac.dops2.toppr.systems TXT [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-rfig.dops2.toppr.systems A [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"Desired change: CREATE dummy-rfig.dops2.toppr.systems TXT [Id: /hostedzone/Z055666939ELBYE3XXXXX]\",\"time\":\"2022-01-28T16:26:05+05:30\"}\n{\"level\":\"info\",\"msg\":\"10 record(s) in zone dops2.toppr.systems. [Id: /hostedzone/Z055666939ELBYE3XXXXX] were successfully updated\",\"time\":\"2022-01-28T16:26:06+05:30\"}\n```\n\n## Contribution\n\nWhen teams start using dops, it's likely that needs of various other source *(perhaps read endpoints from text file? json over http?)* and providers will arise. More information about design and how-to contribute documents will be added when interest to contribute is shown in our [engienering forum](https://discuss.toppr.systems).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraamsri%2Fdops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraamsri%2Fdops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraamsri%2Fdops/lists"}