How to use DNS SDK in Golang
Tags: go, network, development, programming
Published: 2023-05-31 07:18:56

So we're gonna try to manipulate DNS records using go SDK (not REST API directly). I went through first 2 page of google search results, and companies that providing SDK for Go were:

1.    IBM [networking-go-sdk](https://github.com/IBM/networking-go-sdk) - 161.26.0.10 and 161.26.0.11 - timedout resolving their own website
2.    AWS [route53](https://docs.aws.amazon.com/sdk-for-go/api/service/route53/) - 169.254.169.253 - timedout resolving their own website
3.    DNSimple [dnsimple-go](https://dnsimple.com/api/go) - 162.159.27.4 and 199.247.155.53 - 160-180ms and 70-75ms from SG
4.    Google [googleapis](https://github.com/googleapis/google-api-go-client/tree/main/examples) - 8.8.8.8 and 8.8.4.4 - 0ms for both from SG
5.    GCore [gcore-dns-sdk-go](https://github.com/G-Core/gcore-dns-sdk-go) - 199.247.155.53 and 2.56.220.2 - 0ms and 0-171ms (171ms on first hit only, the rest is 0ms) from SG

I've used google SDK before for non-DNS stuff, a bit too raw and so many required steps. You have to create a project, enable API, create service account, set permission for that account, download credentials.json, then hit using their SDK -- not really straightforward, so today we're gonna try G-Core's DNS, apparently it's very easy, just need to visit their website and sign up, profile > API Tokens > Create Token, copy it to some file (for example: `.token` file).

![create token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4ekvy5lraudyh699awx.jpg)

This is example how you can create a zone, add an A record, and delete everything:

```
package main

import (
  "context"
  _ "embed"
  "strings"
  "time"  
  "github.com/G-Core/gcore-dns-sdk-go"
  "github.com/kokizzu/gotro/L"
)

//go:embed .token
var apiToken stringfunc main() {
  apiToken = strings.TrimSpace(apiToken)

  // init SDK
  sdk := dnssdk.NewClient(dnssdk.PermanentAPIKeyAuth(apiToken), func(client *dnssdk.Client) {
    client.Debug = true
  })
  ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  defer cancel()
  const zoneName = `benalu2.dev`

  // create zone
  _, err := sdk.CreateZone(ctx, zoneName)
  if err != nil && !strings.Contains(err.Error(), `already exists`) {
    L.PanicIf(err, `sdk.CreateZone`)
  }

  // get zone
  zoneResp, err := sdk.Zone(ctx, zoneName)
  L.PanicIf(err, `sdk.Zone`)
  L.Describe(zoneResp)
  // add A record
  err = sdk.AddZoneRRSet(ctx,
    zoneName,        // zone
    `www.`+zoneName, // name
    `A`,             // rrtype
    []dnssdk.ResourceRecord{
      { // https://apidocs.gcore.com/dns#tag/rrsets/operation/CreateRRSet
        Content: []any{
          `194.233.65.174`,
        },
      },
    },
    120, // TTL
  )
  L.PanicIf(err, `AddZoneRRSet`)

  // get A record
  rr, err := sdk.RRSet(ctx, zoneName, `www.`+zoneName, `A`)
  L.PanicIf(err, `sdk.RRSet`)
  L.Describe(rr)  // delete A record
  err = sdk.DeleteRRSet(ctx, zoneName, `www.`+zoneName, `A`)
  L.PanicIf(err, `sdk.DeleteRRSet`)

  // delete zone
  err = sdk.DeleteZone(ctx, zoneName)
  L.PanicIf(err, `sdk.DeleteZone`)
}
```

The full source code repo is [here](https://github.com/kokizzu/dns1). Apparently it's very easy to manipulate DNS record using their SDK, after adding record programmatically, all I need to do is just delegate (set authoritative nameserver) to their NS: ns1.gcorelabs.net and ns2.gcdn.services.In my case because I bought the domain name on google domains, then I just need to change this: 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9q2pdbn6ajpyxep7h0u.png)
 
Then just wait it to be delegated properly (until all DNS servers that still caching the old authorized NS cleared up), I guess that it. This article republished with permission from kokizzu's personal [blog](https://kokizzu.blogspot.com/2023/04/how-to-use-dns-sdk-in-golang.html)