diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fb40b80..36a4815 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,10 +16,10 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.24' - name: Check out code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{github.event.pull_request.head.sha}} diff --git a/.github/workflows/release-on-tag.yaml b/.github/workflows/release-on-tag.yaml index aa2afe4..7cb7dfb 100644 --- a/.github/workflows/release-on-tag.yaml +++ b/.github/workflows/release-on-tag.yaml @@ -26,7 +26,7 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: softprops/action-gh-release@v2 with: generate_release_notes: true diff --git a/.golangci.yaml b/.golangci.yaml index 578c6d7..d178ef8 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,5 +1,6 @@ ---- +version: "2" + linters: + default: none enable: - staticcheck - disable-all: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3c6590d..c1d5a2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: check-yaml - id: check-merge-conflict - repo: https://github.com/golangci/golangci-lint - rev: v1.63.4 + rev: v2.3.1 hooks: - id: golangci-lint - repo: https://github.com/dnephin/pre-commit-golang diff --git a/README.md b/README.md index 688a482..7ab1657 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Active24.cz client in Go -This is client library to interact with [Active24 API](https://faq.active24.com/eng/739445-REST-API-for-developers?l=en-US). +This is client library to interact with [Active24 APIv2](https://www.active24.cz/centrum-napovedy/api-rozhrani). Currently, only subset of API is implemented, but contributions are always welcome. ## Usage @@ -8,14 +8,21 @@ Currently, only subset of API is implemented, but contributions are always welco ```go package main -import "github.com/rkosegi/active24-go/active24" +import "github.com/hostalp/active24-go/active24" func main() { - client := active24.New("my-secret-api-token") + client := active24.New("my-secret-api-key", "my-secret-api-secret") - alias := "host1" - _, err := client.Dns().With("example.com").Create(active24.DnsRecordTypeA, &active24.DnsRecord{ - Alias: &alias, + recordType := string(active24.DnsRecordTypeA) + hostName := "host1" // Short hostname (excl. the domain) + ipAddress := "1.2.3.4" + ttl := 600 + + _, err := client.Dns().With("example.com", 12345678).Create(&active24.DnsRecord{ + Type: &recordType, + Name: hostName; + Content: &ipAddress, + Ttl: ttl, }) if err != nil { panic(err) diff --git a/active24/client.go b/active24/client.go index 88a0f54..30311b2 100644 --- a/active24/client.go +++ b/active24/client.go @@ -17,15 +17,17 @@ limitations under the License. package active24 import ( + "crypto/hmac" + "crypto/sha1" + "encoding/hex" "fmt" "io" - "k8s.io/klog/v2" "net/http" + "net/url" + "path" "time" -) -const ( - SandboxToken = "123456qwerty-ok" + "k8s.io/klog/v2" ) type Option func(c *client) @@ -50,19 +52,19 @@ type ApiError interface { type Client interface { // Dns provides interface to interact with DNS records Dns() Dns - // Domains provides interface to interact with domains - Domains() Domains } -func New(apiKey string, opts ...Option) Client { +func New(apiKey string, apiSecret string, opts ...Option) Client { c := &client{ h: helper{ - apiEndpoint: "https://api.active24.com", - auth: apiKey, + apiEndpoint: "https://rest.active24.cz", + authKey: apiKey, + authSecret: apiSecret, c: http.Client{ Timeout: time.Second * 10, }, - l: klog.NewKlogr(), + l: klog.NewKlogr(), + maxPages: 100, // default max pages to prevent infinite loops }, } for _, opt := range opts { @@ -81,12 +83,6 @@ func (c *client) Dns() Dns { } } -func (c *client) Domains() Domains { - return &domains{ - h: c.h, - } -} - type apiError struct { err error resp *http.Response @@ -102,21 +98,57 @@ func (a *apiError) Response() *http.Response { type helper struct { apiEndpoint string - auth string + authKey string + authSecret string c http.Client l klog.Logger + maxPages int +} + +func (ch *helper) getSignature(message, key string) string { + h := hmac.New(sha1.New, []byte(key)) + h.Write([]byte(message)) + return hex.EncodeToString(h.Sum(nil)) } -func (ch *helper) do(method string, suffix string, body io.Reader) (*http.Response, error) { - r, err := http.NewRequest(method, fmt.Sprintf("%s/%s", ch.apiEndpoint, suffix), body) +func (ch *helper) do(reqMethod string, reqPath string, reqBody io.Reader) (*http.Response, error) { + return ch.doWithParams(reqMethod, reqPath, nil, reqBody) +} + +func (ch *helper) doWithParams(reqMethod string, reqPath string, reqParams url.Values, reqBody io.Reader) (*http.Response, error) { + reqPath = path.Join("/", reqPath) + reqTimestamp := time.Now() + canonicalRequest := fmt.Sprintf("%s %s %d", reqMethod, reqPath, reqTimestamp.Unix()) + authSignature := ch.getSignature(canonicalRequest, ch.authSecret) + + r, err := http.NewRequest(reqMethod, fmt.Sprintf("%s%s", ch.apiEndpoint, reqPath), reqBody) if err != nil { return nil, err } - r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", ch.auth)) + r.URL.RawQuery = reqParams.Encode() r.Header.Set("Content-Type", "application/json") r.Header.Set("Accept", "application/json") - ch.l.V(4).Info("Calling API", "method", method, "url", r.URL.String()) - return ch.c.Do(r) + r.Header.Set("Date", reqTimestamp.UTC().Format(time.RFC3339)) + r.SetBasicAuth(ch.authKey, authSignature) + ch.l.V(4).Info("Calling API", "method", reqMethod, "URL", r.URL.String()) + + // Log the request + /* dumpReq, dumpErr := httputil.DumpRequestOut(r, true) + if dumpErr != nil { + return nil, dumpErr + } + ch.l.V(4).Info("doWithParams", "REQUEST", string(dumpReq)) */ + + resp, err := ch.c.Do(r) + + // Log the response + /* dumpResp, dumpErr := httputil.DumpResponse(resp, true) + if dumpErr != nil { + return nil, dumpErr + } + ch.l.V(4).Info("doWithParams", "RESPONSE", string(dumpResp)) */ + + return resp, err } func apiErr(resp *http.Response, err error) ApiError { diff --git a/active24/client_test.go b/active24/client_test.go deleted file mode 100644 index 461cf1d..0000000 --- a/active24/client_test.go +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2023 Richard Kosegi - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package active24 - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestDummy(t *testing.T) { - client := New(SandboxToken, ApiEndpoint("https://sandboxapi.active24.com")) - assert.NotNil(t, client.Dns()) - assert.NotNil(t, client.Domains()) -} diff --git a/active24/dns.go b/active24/dns.go index 4bae27a..d3b9be4 100644 --- a/active24/dns.go +++ b/active24/dns.go @@ -22,146 +22,214 @@ import ( "fmt" "io" "net/http" + "net/url" + "strconv" + "strings" ) type DnsRecordType string //goland:noinspection GoUnusedConst const ( - DnsRecordTypeA = DnsRecordType("a") - DnsRecordTypeAAAA = DnsRecordType("aaaa") - DnsRecordTypeCAA = DnsRecordType("caa") - DnsRecordTypeCNAME = DnsRecordType("cname") - DnsRecordTypeMX = DnsRecordType("mx") - DnsRecordTypeNS = DnsRecordType("ns") - DnsRecordTypeSRV = DnsRecordType("srv") - DnsRecordTypeSSHFP = DnsRecordType("sshfp") - DnsRecordTypeTLSA = DnsRecordType("tlsa") - DnsRecordTypeTXT = DnsRecordType("txt") + DnsRecordTypeA = DnsRecordType("A") + DnsRecordTypeAAAA = DnsRecordType("AAAA") + DnsRecordTypeANAME = DnsRecordType("ANAME") + DnsRecordTypeCAA = DnsRecordType("CAA") + DnsRecordTypeCNAME = DnsRecordType("CNAME") + DnsRecordTypeMX = DnsRecordType("MX") + DnsRecordTypeSRV = DnsRecordType("SRV") + DnsRecordTypeTXT = DnsRecordType("TXT") + DnsRecordTypeCERT = DnsRecordType("CERT") + DnsRecordTypeLOC = DnsRecordType("LOC") + DnsRecordTypeSSHFP = DnsRecordType("SSHFP") + DnsRecordTypeTLSA = DnsRecordType("TLSA") + DnsRecordTypeDS = DnsRecordType("DS") + DnsRecordTypeNS = DnsRecordType("NS") ) -type DnsDomainList []string - // Dns provides a way to interact with DNS domains type Dns interface { - // List returns a list of domains which have DNS records managed by Active 24. - List() (DnsDomainList, ApiError) - // With returns interface to interact with DNS records in given domain - With(domain string) DnsRecordActions + // With returns interface to interact with DNS records in given service ID (domain) + With(domain string, serviceID int) DnsRecordActions } type DnsRecord struct { - HashId *string `json:"hashId,omitempty"` - Type *string `json:"type,omitempty"` - Ttl int `json:"ttl"` - Name string `json:"name"` - Port *int `json:"port,omitempty"` - Priority *int `json:"priority,omitempty"` - Target *string `json:"target,omitempty"` - Weight *int `json:"weight,omitempty"` - NameServer *string `json:"nameserver,omitempty"` - Ip *string `json:"ip,omitempty"` - CaaValue *string `json:"caaValue,omitempty"` - Flags *int `json:"flags,omitempty"` - Tag *string `json:"tag,omitempty"` - Alias *string `json:"alias,omitempty"` - MailServer *string `json:"mailserver,omitempty"` - Algorithm *int `json:"algorithm,omitempty"` - FingerprintType *int `json:"fingerprintType,omitempty"` - CertificateUsage *int `json:"certificateUsage,omitempty"` - Hash *string `json:"hash,omitempty"` - MatchingType *int `json:"matchingType,omitempty"` - Selector *int `json:"selector,omitempty"` - Text *string `json:"text,omitempty"` + Type *string `json:"type,omitempty"` + ID *int `json:"id,omitempty"` + Name string `json:"name"` + Content *string `json:"content,omitempty"` + Ttl int `json:"ttl"` + Priority *int `json:"priority,omitempty"` + Port *int `json:"port,omitempty"` + Weight *int `json:"weight,omitempty"` +} + +type DnsRecordPaginatedCollection struct { + CurrentPage *int `json:"currentPage,omitempty"` + TotalPages *int `json:"totalPages,omitempty"` + TotalRecords *int `json:"totalRecords,omitempty"` + RowsPerPage *int `json:"rowsPerPage,omitempty"` + NextPageUrl *string `json:"nextPageUrl,omitempty"` + Data []DnsRecord `json:"data,omitempty"` } // DnsRecordActions allows interaction with DNS records type DnsRecordActions interface { // Create creates a new DNS record - Create(DnsRecordType, *DnsRecord) ApiError + Create(*DnsRecord) ApiError // List lists all DNS records in this domain. - List() ([]DnsRecord, ApiError) + ListAll() ([]DnsRecord, ApiError) + // List lists DNS records of specified type or name in this domain. + List(DnsRecordType, string) ([]DnsRecord, ApiError) + // ListPage lists 1 page of DNS records of specified type or name in this domain. + ListPage(DnsRecordType, string, string, int) ([]DnsRecord, string, int, ApiError) // Update updates an existing DNS record - Update(DnsRecordType, *DnsRecord) ApiError - // Delete removes single DNS record based on its hash ID - Delete(string) ApiError + Update(int, *DnsRecord) ApiError + // Delete removes single DNS record based on its ID + Delete(int) ApiError } type dns struct { h helper } -func (d *dns) List() (DnsDomainList, ApiError) { - resp, err := d.h.do(http.MethodGet, "dns/domains/v1", nil) - if err != nil { - return nil, apiErr(nil, err) - } - defer func(b io.ReadCloser) { - _ = b.Close() - }(resp.Body) - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, apiErr(resp, err) - } - doms := make([]string, 0) - err = json.Unmarshal(body, &doms) - if err != nil { - return nil, apiErr(resp, err) - } - return doms, apiErr(resp, nil) -} - -func (d *dns) With(domain string) DnsRecordActions { +func (d *dns) With(domain string, serviceID int) DnsRecordActions { return &domainAction{ - h: d.h, - dom: domain, + h: d.h, + dom: domain, + svcID: serviceID, } } type domainAction struct { - h helper - dom string + h helper + dom string + svcID int } -func (d *domainAction) Create(recType DnsRecordType, r *DnsRecord) ApiError { - return apiErr(d.change(http.MethodPost, string(recType), r)) +func (d *domainAction) ListAll() ([]DnsRecord, ApiError) { + return d.List("", "") } -func (d *domainAction) change(method string, sub string, r *DnsRecord) (*http.Response, error) { - data, err := json.Marshal(r) +func (d *domainAction) List(recType DnsRecordType, recName string) ([]DnsRecord, ApiError) { + // Get first page + allRecords, nextPageUrl, nextPage, err := d.ListPage(recType, recName, "", 0) if err != nil { return nil, err } - return d.h.do(method, fmt.Sprintf("dns/%s/%s/v1", d.dom, sub), bytes.NewBuffer(data)) + + // Keep getting next pages while we have either nextPageUrl or nextPage + pageCount := 1 + for (nextPageUrl != "" || nextPage > 0) && pageCount < d.h.maxPages { + pageCount++ + var pageRecords []DnsRecord + pageRecords, nextPageUrl, nextPage, err = d.ListPage(recType, recName, nextPageUrl, nextPage) + if err != nil { + return nil, err + } + allRecords = append(allRecords, pageRecords...) + } + if pageCount >= d.h.maxPages { + return nil, apiErr(nil, fmt.Errorf("maximum page limit reached in List, maxPages: %d, increase the limit in the configuration", d.h.maxPages)) + } + return allRecords, nil } -func (d *domainAction) List() ([]DnsRecord, ApiError) { - resp, err := d.h.do(http.MethodGet, fmt.Sprintf("dns/%s/records/v1", d.dom), nil) +func (d *domainAction) ListPage(recType DnsRecordType, recName string, recPageUrl string, recPage int) ([]DnsRecord, string, int, ApiError) { + ret, err := d.ListPaginated(recType, recName, recPageUrl, recPage) if err != nil { - return nil, apiErr(nil, err) + return nil, "", 0, err + } + + var nextPageUrl string + var nextPage int + + switch { + // Get the next page request paramater (query string) from the field nextPageUrl of the last response - preferred + case ret.NextPageUrl != nil && *ret.NextPageUrl != "": + // Typical response field nextPageUrl: "/?page=2", strip all leading "/?" characters from it + nextPageUrl = strings.TrimLeft(*ret.NextPageUrl, "/?") + // Calculate the next page from the currentPage and totalPages fields of the last response - only if not set via nextPageUrl + case ret.CurrentPage != nil && ret.TotalPages != nil && *ret.CurrentPage < *ret.TotalPages: + nextPage = *ret.CurrentPage + 1 + } + return ret.Data, nextPageUrl, nextPage, err +} + +func (d *domainAction) ListPaginated(recType DnsRecordType, recName string, recPageUrl string, recPage int) (DnsRecordPaginatedCollection, ApiError) { + // HTTP request params + reqParams := url.Values{} + reqParams.Add("descending", "false") + reqParams.Add("sortBy", "name") + if recType != "" { + reqParams.Add("filters[type]", fmt.Sprintf("[\"%s\"]", recType)) + } + if recName != "" { + reqParams.Add("filters[name]", recName) + } + var ret DnsRecordPaginatedCollection + // Requested page obtained from the nextPageUrl field of the last response - preferred + hasRecPageUrl := false + if recPageUrl != "" { + recPageUrlValues, err := url.ParseQuery(recPageUrl) + if err != nil { + return ret, apiErr(nil, err) + } + for k, v := range recPageUrlValues { + if k != "" && len(v) > 0 && v[0] != "" { + reqParams.Add(k, v[0]) + hasRecPageUrl = true + } + break + } + } + // Requested page calculated from the currentPage and totalPages fields of the last response - only if not set via nextPageUrl + if !hasRecPageUrl && recPage > 1 { + reqParams.Add("page", strconv.Itoa(recPage)) + } + + resp, err := d.h.doWithParams(http.MethodGet, fmt.Sprintf("v2/service/%d/dns/record", d.svcID), reqParams, nil) + if err != nil { + return ret, apiErr(nil, err) } defer func(b io.ReadCloser) { _ = b.Close() }(resp.Body) if resp.StatusCode > 399 && resp.StatusCode < 600 { - return nil, apiErr(resp, fmt.Errorf("invalid response from api: %d", resp.StatusCode)) + return ret, apiErr(resp, fmt.Errorf("invalid response from API: %d", resp.StatusCode)) } body, err := io.ReadAll(resp.Body) if err != nil { - return nil, apiErr(resp, err) + return ret, apiErr(resp, err) } - ret := make([]DnsRecord, 0) + //ret := make([]DnsRecord, 0) err = json.Unmarshal(body, &ret) if err != nil { - return nil, apiErr(resp, err) + return ret, apiErr(resp, err) } return ret, apiErr(resp, nil) } -func (d *domainAction) Update(recType DnsRecordType, r *DnsRecord) ApiError { - return apiErr(d.change(http.MethodPut, string(recType), r)) +func (d *domainAction) Create(r *DnsRecord) ApiError { + data, err := json.Marshal(r) + if err != nil { + return apiErr(nil, err) + } + return apiErr(d.h.do(http.MethodPost, fmt.Sprintf("v2/service/%d/dns/record", d.svcID), bytes.NewBuffer(data))) +} + +func (d *domainAction) change(method string, recordID int, r *DnsRecord) (*http.Response, error) { + data, err := json.Marshal(r) + if err != nil { + return nil, err + } + return d.h.do(method, fmt.Sprintf("v2/service/%d/dns/record/%d", d.svcID, recordID), bytes.NewBuffer(data)) +} + +func (d *domainAction) Update(ID int, r *DnsRecord) ApiError { + return apiErr(d.change(http.MethodPut, ID, r)) } -func (d *domainAction) Delete(hashId string) ApiError { - return apiErr(d.h.do(http.MethodDelete, fmt.Sprintf("/dns/%s/%s/v1", d.dom, hashId), nil)) +func (d *domainAction) Delete(ID int) ApiError { + return apiErr(d.h.do(http.MethodDelete, fmt.Sprintf("v2/service/%d/dns/record/%d", d.svcID, ID), nil)) } diff --git a/active24/dns_test.go b/active24/dns_test.go deleted file mode 100644 index 14d0c5e..0000000 --- a/active24/dns_test.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2023 Richard Kosegi - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package active24 - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestDnsList(t *testing.T) { - client := New(SandboxToken, ApiEndpoint("https://sandboxapi.active24.com")) - list, err := client.Dns().List() - assert.Nil(t, err) - assert.NotNil(t, list) -} diff --git a/active24/domains.go b/active24/domains.go deleted file mode 100644 index bff6ea5..0000000 --- a/active24/domains.go +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2023 Richard Kosegi - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package active24 - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "time" -) - -type DomainInfo struct { - Name string `json:"name"` - Status string `json:"status"` - ExpirationDate uint64 `json:"expirationDate"` - HolderFullName string `json:"holderFullName"` - Payable bool `json:"payable"` - PayedTo uint64 `json:"payedTo"` -} - -type DomainConfigurationField struct { - Error string `json:"error"` - Name string `json:"name"` - Order int `json:"order"` - Required bool `json:"required"` - Type string `json:"type"` - Value interface{} `json:"value"` - ValidationRegex string `json:"validationRegex"` - WriteOnly bool `json:"writeOnly"` -} - -type DomainConfigurationPart struct { - Fields []DomainConfigurationField `json:"fields"` - Updatable bool `json:"updatable"` - ProcessState *string `json:"processState"` -} - -type DomainConfiguration struct { - Holder DomainConfigurationPart `json:"domainHolderConfiguration"` - AdminContact DomainConfigurationPart `json:"domainAdminContactConfiguration"` - Nameserver DomainConfigurationPart `json:"domainNameserverConfiguration"` -} - -type DomainList []DomainInfo - -type Domains interface { - //List returns a list of domains where user is owner or payer. - List() (DomainList, ApiError) - // Expiration gets domain expiration date - Expiration(domain string) (*time.Time, ApiError) - //Status get domain status - checks if domain can be registered. - Status(domain string) (*string, ApiError) -} - -type domains struct { - h helper -} - -func (d *domains) List() (DomainList, ApiError) { - resp, err := d.h.do(http.MethodGet, "domains/v1", nil) - if err != nil { - return nil, apiErr(nil, err) - } - defer func(b io.ReadCloser) { - _ = b.Close() - }(resp.Body) - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, apiErr(resp, err) - } - doms := make([]DomainInfo, 0) - err = json.Unmarshal(body, &doms) - if err != nil { - return nil, apiErr(resp, err) - } - return doms, apiErr(resp, nil) -} - -func (d *domains) Expiration(domain string) (*time.Time, ApiError) { - resp, err := d.h.do(http.MethodGet, fmt.Sprintf("domains/%s/expiration/v1", domain), nil) - if err != nil { - return nil, apiErr(nil, err) - } - defer func(b io.ReadCloser) { - _ = b.Close() - }(resp.Body) - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, apiErr(resp, err) - } - ret, err := time.Parse(time.RFC3339, string(body)) - if err != nil { - return nil, apiErr(resp, err) - } - return &ret, apiErr(resp, nil) -} - -func (d *domains) Status(domain string) (*string, ApiError) { - resp, err := d.h.do(http.MethodGet, fmt.Sprintf("domains/%s/expiration/v1", domain), nil) - if err != nil { - return nil, apiErr(nil, err) - } - defer func(b io.ReadCloser) { - _ = b.Close() - }(resp.Body) - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, apiErr(resp, err) - } - ret := string(body) - return &ret, apiErr(resp, nil) -} diff --git a/examples/dns/list_and_create_dns_record.go b/examples/dns/list_and_create_dns_record.go index f2be192..bfe8f7e 100644 --- a/examples/dns/list_and_create_dns_record.go +++ b/examples/dns/list_and_create_dns_record.go @@ -18,24 +18,17 @@ package main import ( "fmt" - "github.com/rkosegi/active24-go/active24" + + "github.com/hostalp/active24-go/active24" ) func main() { - client := active24.New("123456qwerty-ok", active24.ApiEndpoint("https://sandboxapi.active24.com")) + client := active24.New("ak48l3h7-ak5d-qn4t-p8gc-b6fs8c3l", "ajvkeo3y82ndsu2smvxy3o36496dcascksldncsq", active24.ApiEndpoint("https://sandboxapi.active24.com")) dns := client.Dns() - //list all domains - list, err := dns.List() - if err != nil { - panic(err) - } - for _, d := range list { - print(d) - } //list DNS records in domain example.com - recs, err := dns.With("example.com").List() + recs, err := dns.With("example.com", 12345678).ListAll() if err != nil { panic(err) } @@ -44,9 +37,16 @@ func main() { } //create CNAME record - alias := "host1" - err = dns.With("example.com").Create(active24.DnsRecordTypeA, &active24.DnsRecord{ - Alias: &alias, + recordType := string(active24.DnsRecordTypeCNAME) + hostName := "host1" + alias := "host.example.com" + ttl := 600 + + err = dns.With("example.com", 12345678).Create(&active24.DnsRecord{ + Type: &recordType, + Name: hostName, + Content: &alias, + Ttl: ttl, }) if err != nil { panic(err) diff --git a/examples/domains/list_domains.go b/examples/domains/list_domains.go deleted file mode 100644 index 9b8e55f..0000000 --- a/examples/domains/list_domains.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2023 Richard Kosegi - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" - "github.com/rkosegi/active24-go/active24" -) - -func main() { - client := active24.New(active24.SandboxToken, active24.ApiEndpoint("https://sandboxapi.active24.com")) - dom := client.Domains() - //list all domains - list, err := dom.List() - if err != nil { - panic(err) - } - for _, d := range list { - fmt.Printf("Name: %s, Status: %s, Holder: %s", d.Name, d.Status, d.HolderFullName) - } -} diff --git a/go.mod b/go.mod index db7d674..dc991d7 100644 --- a/go.mod +++ b/go.mod @@ -12,18 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -module github.com/rkosegi/active24-go +module github.com/hostalp/active24-go -go 1.21 +go 1.24 -require ( - github.com/stretchr/testify v1.10.0 - k8s.io/klog/v2 v2.130.1 -) +require k8s.io/klog/v2 v2.130.1 -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v1.4.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) +require github.com/go-logr/logr v1.4.3 // indirect diff --git a/go.sum b/go.sum index 9687f1f..910d228 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,4 @@ -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/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -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/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -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.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=