Compare commits

..

17 commits

Author SHA1 Message Date
dependabot[bot]
66d86fb092 Bump github.com/stretchr/testify from 1.8.0 to 1.8.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-31 16:38:21 +01:00
Sighery
bfc94ffc04 Switch actions/checkout to major v3 version
It's a bit of a pain to constantly update patch versions, as this is
just CI and unrelated to the main focus which is the codebase. So in
these cases, I don't want to run CI again just because the `checkout`
action had an update.
2022-10-31 16:36:56 +01:00
Sighery
997979f1b8 Adapt to API using string ID
Previously the API would use integer IDs. This has been silently
changed at some point, and now all IDs are strings, even though they
seem to still be numeric.

From this Github issue https://github.com/go-acme/lego/issues/1685
Njalla devs have confirmed this was an intentional change and all IDs
will be strings going forward, meaning we shouln't just have an
adapter to keep using our integer IDs, since they might also move away
from numeric IDs in the future, and switch to UUID or some other
alphanumeric ID.
2022-08-14 20:46:25 +02:00
Sighery
ef93a5772e Update project to Go v1.17 2022-08-14 20:37:16 +02:00
Sighery
2aded968d2 Remove CodeQL Analysis CI workflow
I don't use it and so far haven't found it useful either. I might add
it back at some point after I get more time to tinker with it.
2022-08-14 17:38:26 +02:00
dependabot[bot]
cc5aa6c9ed Bump github.com/stretchr/testify from 1.7.0 to 1.8.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-14 17:34:52 +02:00
dependabot[bot]
6afd3822b2 Bump actions/checkout from 2.4.0 to 3.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3.0.2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-14 17:32:25 +02:00
dependabot[bot]
b7148fab83 Bump actions/checkout from 2.3.4 to 2.4.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-08 21:59:34 +01:00
Sighery
ea449f0dda Update and improve documentation
`find-domains` has been added to the list of covered endpoints. The
README usage section has been extended to show some basic operations
with records, and point to documentation and tests for learning usage,
and to the Njalla Terraform provider for actual code usage examples.
2021-09-12 00:10:59 +02:00
kayos@tcp.direct
cf5fdbb592 Add find-domains endpoint
The `find-domains` endpoint allows you to check the availability and
price of domains for a given query. So if the query was `example`, it'd
show availability and price of domains `example.com`, `example.net`,
etc.
2021-09-11 23:17:29 +02:00
dependabot[bot]
3b41066138 Bump actions/checkout from 2 to 2.3.4
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 2.3.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v2.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-15 09:19:15 +02:00
dependabot[bot]
6af1099b71 Bump github.com/stretchr/testify from 1.6.1 to 1.7.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.6.1...v1.7.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 18:04:53 +02:00
Sighery
4570ff381b
Add Action for new GitHub CodeQL analysis 2020-10-02 09:01:08 +02:00
Sighery
023a8ba939 Switch to native Dependabot
Previously Dependabot was a third-party service. Now that Dependabot
has been bought by GitHub, it's being integrated into GitHub itself as
a native service. To make use of the native version, the configuration
changes slightly, and it goes under a new directory.
2020-08-12 03:22:45 +02:00
dependabot-preview[bot]
e57854683b Bump github.com/stretchr/testify from 1.6.0 to 1.6.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.6.0...v1.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 10:21:20 +02:00
dependabot-preview[bot]
797513210f Bump github.com/stretchr/testify from 1.5.1 to 1.6.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:10:49 +02:00
Sighery
4cbecbf44d Dependabot: Update GitHub Actions 2020-05-17 23:50:06 +02:00
10 changed files with 258 additions and 34 deletions

View file

@ -1,6 +0,0 @@
version: 1
update_configs:
- package_manager: "go:modules"
directory: "/"
update_schedule: "daily"

12
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View file

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install dependencies
run: go get

View file

@ -11,6 +11,7 @@ are:
* `add-record`
* `edit-record`
* `remove-record`
* `find-domains`
**TO NOTE**: Even though `record` methods are implemented, I'm fairly certain
they'll fail (silently or not) in some cases. I deal mostly with `TXT`, `MX`,
@ -28,6 +29,11 @@ cover all types of DNS records), as long as they're all tested and documented.
### Usage
Most of the methods are pretty self-explanatory if you read the documentation
and read the function signature. Some of the most "complex" operations, like
creating/updating records can be figured out from the tests. But here's some
examples:
```golang
package main
@ -41,14 +47,79 @@ func main() {
token := "api-token"
domain := "your-domain"
records, err := ListRecords(token, domain)
if err != nil {
fmt.Println(err)
// 1. Listing records in a domain
records, err1 := gonjalla.ListRecords(token, domain)
if err1 != nil {
fmt.Println(err1)
}
// It will print an array of gonjalla.Record
fmt.Println(records)
// 2. Adding a new record to a domain
priority := 10
adding := gonjalla.Record{
Name: "@",
Type: "MX",
Content: "testing.com",
TTL: 10800,
Priority: &priority,
}
confirmation, err2 := gonjalla.AddRecord(token, domain, adding)
if err2 != nil {
fmt.Println(err2)
}
// confirmation will be a gonjalla.Record with the response from the
// server, so it should be pretty similar to your starting
// gonjalla.Record but this will contain the ID filled in, which is
// needed for updates
fmt.Println(confirmation)
// 3. Updating a record of a given domain
// Let's assume we got the ID of the record created in step 2
// and we want to change either some or all fields
id_we_look_for := confirmation.ID
// The edit method updates all the fields due to limitations of the
// API. Get the record from the API if you only want to change some,
// but not all, fields
for _, record := range records {
if record.ID == id_we_look_for {
record.Content = "edited-value"
record.TTL = 900
err3 := gonjalla.EditRecord(token, domain, record)
if err3 != nil {
fmt.Println(err3)
}
}
}
// If you don't care about overwriting previous values
new_priority := 20
editing := gonjalla.Record{
ID: id_we_look_for,
Name: "@",
Type: "MX",
Content: "edited-thing",
TTL: 300,
Priority: &new_priority,
}
err4 := gonjalla.EditRecord(token, domain, editing)
if err4 != nil {
fmt.Println(err4)
}
}
```
Some actual code making use of this library (mainly dealing with records) can
also be seen at the [Njalla Terraform provider].
[Njalla]: https://njal.la
[official API]: https://njal.la/api/
[Njalla Terraform provider]: https://github.com/Sighery/terraform-provider-njalla

View file

@ -15,6 +15,13 @@ type Domain struct {
MaxNameservers *int `json:"max_nameservers,omitempty"`
}
// Domain availability and price data returned by `find-domains`
type MarketDomain struct {
Name string `json:"name"`
Status string `json:"status"`
Price int `json:"price"`
}
// ListDomains returns a listing of domains with minimal data
func ListDomains(token string) ([]Domain, error) {
params := map[string]interface{}{}
@ -56,3 +63,29 @@ func GetDomain(token string, domain string) (Domain, error) {
return domainStruct, nil
}
// FindDomains returns availability and price information for a query.
// If query was `example`, then it'd show availability and price of
// domains `example.com`, `example.net`, etc.
func FindDomains(token string, query string) ([]MarketDomain, error) {
params := map[string]interface{}{
"query": query,
}
data, err := Request(token, "find-domains", params)
if err != nil {
return nil, err
}
type Response struct {
Domains []MarketDomain `json:"domains"`
}
var response Response
err = json.Unmarshal(data, &response)
if err != nil {
return nil, err
}
return response.Domains, nil
}

View file

@ -161,3 +161,101 @@ func TestGetDomainError(t *testing.T) {
_, err := GetDomain(token, domain)
assert.Error(t, err)
}
func TestFindDomainsExpected(t *testing.T) {
token := "test-token"
query := "testing"
Client = &mocks.MockClient{}
testData := `{
"result": {
"jsonrpc": "2.0",
"domains": [
{
"name": "testing.com",
"status": "taken",
"price": 45
},
{
"name": "testing.net",
"status": "available",
"price": 30
},
{
"name": "testing.rocks",
"status": "in progress",
"price": 15
},
{
"name": "testing.express",
"status": "failed",
"price": 75
}
]
}
}`
r := ioutil.NopCloser(bytes.NewReader([]byte(testData)))
mocks.GetDoFunc = func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
}
domains, err := FindDomains(token, query)
if err != nil {
t.Error(err)
}
expected := []MarketDomain{
{
Name: "testing.com",
Status: "taken",
Price: 45,
},
{
Name: "testing.net",
Status: "available",
Price: 30,
},
{
Name: "testing.rocks",
Status: "in progress",
Price: 15,
},
{
Name: "testing.express",
Status: "failed",
Price: 75,
},
}
assert.Equal(t, domains, expected)
}
func TestFindDomainsError(t *testing.T) {
token := "test-token"
query := "testing"
Client = &mocks.MockClient{}
testData := `{
"jsonrpc": "2.0",
"error": {
"code": 0,
"message": "Testing error"
}
}`
r := ioutil.NopCloser(bytes.NewReader([]byte(testData)))
mocks.GetDoFunc = func(*http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
}
domains, err := FindDomains(token, query)
assert.Nil(t, domains)
assert.Error(t, err)
}

10
go.mod
View file

@ -1,5 +1,11 @@
module github.com/Sighery/gonjalla
go 1.14
go 1.17
require github.com/stretchr/testify v1.5.1
require github.com/stretchr/testify v1.8.1
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

16
go.sum
View file

@ -1,11 +1,17 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -10,7 +10,7 @@ var ValidPriority = []int{0, 1, 5, 10, 20, 30, 40, 50, 60}
// Record struct contains data returned by `list-records`
type Record struct {
ID int `json:"id"`
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
@ -75,7 +75,7 @@ func AddRecord(token string, domain string, record Record) (Record, error) {
// RemoveRecord removes a given record from a given domain.
// If there are no errors it will return `nil`.
func RemoveRecord(token string, domain string, id int) error {
func RemoveRecord(token string, domain string, id string) error {
params := map[string]interface{}{
"domain": domain,
"id": id,
@ -94,6 +94,10 @@ func RemoveRecord(token string, domain string, id int) error {
// its filled fields to send to Njalla.
// So, if you want to only change a given field, get the `Record` object from
// say ListRecords, change the one field you want, and then pass that here.
//
// Note that the record type cannot be changed, so if you want to do so, you'll
// have to remove and create the record again under a different type. Trying to
// change the record type will just return an API error.
func EditRecord(token string, domain string, record Record) error {
marshal, err := json.Marshal(record)
if err != nil {

View file

@ -21,28 +21,28 @@ func TestListRecordsExpected(t *testing.T) {
"result": {
"records": [
{
"id": 1337,
"id": "1337",
"name": "_acme-challenge",
"type": "TXT",
"content": "long-string",
"ttl": 10800
},
{
"id": 1338,
"id": "1338",
"name": "@",
"type": "A",
"content": "1.2.3.4",
"ttl": 3600
},
{
"id": 1339,
"id": "1339",
"name": "@",
"type": "AAAA",
"content": "2001:0DB8:0000:0000:0000:8A2E:0370:7334",
"ttl": 900
},
{
"id": 1340,
"id": "1340",
"name": "@",
"type": "MX",
"content": "mail.protonmail.ch",
@ -70,28 +70,28 @@ func TestListRecordsExpected(t *testing.T) {
expected := []Record{
{
ID: 1337,
ID: "1337",
Name: "_acme-challenge",
Type: "TXT",
Content: "long-string",
TTL: 10800,
},
{
ID: 1338,
ID: "1338",
Name: "@",
Type: "A",
Content: "1.2.3.4",
TTL: 3600,
},
{
ID: 1339,
ID: "1339",
Name: "@",
Type: "AAAA",
Content: "2001:0DB8:0000:0000:0000:8A2E:0370:7334",
TTL: 900,
},
{
ID: 1340,
ID: "1340",
Name: "@",
Type: "MX",
Content: "mail.protonmail.ch",
@ -140,7 +140,7 @@ func TestAddRecordExpected(t *testing.T) {
testData := `{
"jsonrpc": "2.0",
"result": {
"id": 1337,
"id": "1337",
"name": "@",
"type": "MX",
"content": "testing.com",
@ -173,7 +173,7 @@ func TestAddRecordExpected(t *testing.T) {
}
expected := Record{
ID: 1337,
ID: "1337",
Name: "@",
Type: "MX",
Content: "testing.com",
@ -221,7 +221,7 @@ func TestAddRecordError(t *testing.T) {
func TestRemoveRecordExpected(t *testing.T) {
token := "test-token"
domain := "testing.com"
id := 1337
id := "1337"
Client = &mocks.MockClient{}
testData := `{
@ -244,7 +244,7 @@ func TestRemoveRecordExpected(t *testing.T) {
func TestRemoveRecordError(t *testing.T) {
token := "test-token"
domain := "testing.com"
id := 1337
id := "1337"
Client = &mocks.MockClient{}
testData := `{
@ -275,7 +275,7 @@ func TestEditRecordExpected(t *testing.T) {
testData := `{
"jsonrpc": "2.0",
"result": {
"id": 1337,
"id": "1337",
"name": "@",
"type": "MX",
"content": "testing.com",
@ -294,7 +294,7 @@ func TestEditRecordExpected(t *testing.T) {
priority := 10
editing := Record{
ID: 1337,
ID: "1337",
Name: "@",
Type: "MX",
Content: "testing.com",
@ -329,7 +329,7 @@ func TestEditRecordError(t *testing.T) {
priority := 10
editing := Record{
ID: 1337,
ID: "1337",
Name: "@",
Type: "MX",
Content: "testing.com",