Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(dns): Update dns manipulation to egoscale v3 #640

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
55 changes: 17 additions & 38 deletions cmd/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ package cmd

import (
"errors"
"fmt"

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exo "github.com/exoscale/egoscale/v2"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

var dnsCmd = &cobra.Command{
Expand All @@ -18,59 +15,41 @@ var dnsCmd = &cobra.Command{
}

// domainFromIdent returns a DNS domain from identifier (domain name or ID).
func domainFromIdent(ident string) (*exo.DNSDomain, error) {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
if exo.IsValidUUID(ident) {
return globalstate.EgoscaleClient.GetDNSDomain(ctx, account.CurrentAccount.DefaultZone, ident)
}
func domainFromIdent(ident string) (*v3.DNSDomain, error) {
ctx := gContext

domains, err := globalstate.EgoscaleClient.ListDNSDomains(ctx, account.CurrentAccount.DefaultZone)
domainsResp, err := globalstate.EgoscaleV3Client.ListDNSDomains(ctx)
if err != nil {
return nil, err
}

for _, domain := range domains {
if *domain.UnicodeName == ident {
return &domain, nil
}
domain, err := domainsResp.FindDNSDomain(ident)
mlec1 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

return nil, fmt.Errorf("domain %q not found", ident)
return &domain, err
mlec1 marked this conversation as resolved.
Show resolved Hide resolved
}

// domainRecordFromIdent returns a DNS record from identifier (record name or ID) and optional type
func domainRecordFromIdent(domainID, ident string, rType *string) (*exo.DNSDomainRecord, error) {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
if exo.IsValidUUID(ident) {
return globalstate.EgoscaleClient.GetDNSDomainRecord(ctx, account.CurrentAccount.DefaultZone, domainID, ident)
}
func domainRecordFromIdent(domainID v3.UUID, ident string, rType *v3.DNSDomainRecordType) (*v3.DNSDomainRecord, error) {
ctx := gContext

records, err := globalstate.EgoscaleClient.ListDNSDomainRecords(ctx, account.CurrentAccount.DefaultZone, domainID)
domainRecordsResp, err := globalstate.EgoscaleV3Client.ListDNSDomainRecords(ctx, domainID)
if err != nil {
return nil, err
}

var foundRecord *exo.DNSDomainRecord

for _, r := range records {
if rType != nil && *r.Type != *rType {
continue
}

if ident == *r.Name {
if foundRecord != nil {
return nil, errors.New("more than one records were found")
}
t := r
foundRecord = &t
}
domainRecord, err := domainRecordsResp.FindDNSDomainRecord(ident)
if err != nil {
return nil, err
}

if foundRecord == nil {
return nil, fmt.Errorf("no records were found")
if rType != nil && domainRecord.Type != *rType {
return nil, errors.New("record not found (record type doesn't match)")
}

return foundRecord, nil
return &domainRecord, nil
}

func init() {
Expand Down
76 changes: 63 additions & 13 deletions cmd/dns_add.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package cmd

import (
"errors"
"fmt"

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exo "github.com/exoscale/egoscale/v2"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

var dnsAddCmd = &cobra.Command{
Expand All @@ -20,28 +19,79 @@ func init() {
dnsCmd.AddCommand(dnsAddCmd)
}

// Create a map to store the string to CreateDNSDomainRecordRequestType mappings
var dnsRecordTypeMap = map[string]v3.CreateDNSDomainRecordRequestType{
"NS": v3.CreateDNSDomainRecordRequestTypeNS,
"CAA": v3.CreateDNSDomainRecordRequestTypeCAA,
"NAPTR": v3.CreateDNSDomainRecordRequestTypeNAPTR,
"POOL": v3.CreateDNSDomainRecordRequestTypePOOL,
"A": v3.CreateDNSDomainRecordRequestTypeA,
"HINFO": v3.CreateDNSDomainRecordRequestTypeHINFO,
"CNAME": v3.CreateDNSDomainRecordRequestTypeCNAME,
"SSHFP": v3.CreateDNSDomainRecordRequestTypeSSHFP,
"SRV": v3.CreateDNSDomainRecordRequestTypeSRV,
"AAAA": v3.CreateDNSDomainRecordRequestTypeAAAA,
"MX": v3.CreateDNSDomainRecordRequestTypeMX,
"TXT": v3.CreateDNSDomainRecordRequestTypeTXT,
"ALIAS": v3.CreateDNSDomainRecordRequestTypeALIAS,
"URL": v3.CreateDNSDomainRecordRequestTypeURL,
"SPF": v3.CreateDNSDomainRecordRequestTypeSPF,
}
mlec1 marked this conversation as resolved.
Show resolved Hide resolved

// Function to get the DNSDomainRecordRequestType from a string
func StringToDNSDomainRecordRequestType(recordType string) (v3.CreateDNSDomainRecordRequestType, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Function to get the DNSDomainRecordRequestType from a string
func StringToDNSDomainRecordRequestType(recordType string) (v3.CreateDNSDomainRecordRequestType, error) {
// StringToDNSDomainRecordRequestType gets the DNSDomainRecordRequestType from a string
func StringToDNSDomainRecordRequestType(recordType string) (v3.CreateDNSDomainRecordRequestType, error) {

// Lookup the record type in the map
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Lookup the record type in the map

IMHO code is enough explicit here

if recordType, exists := dnsRecordTypeMap[recordType]; exists {
return recordType, nil
}
return "", errors.New("invalid DNS record type")
}

func addDomainRecord(domainIdent, name, rType, content string, ttl int64, priority *int64) error {
domain, err := domainFromIdent(domainIdent)
if err != nil {
return err
}

ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
decorateAsyncOperation(fmt.Sprintf("Adding DNS record %q to %q...", rType, *domain.UnicodeName), func() {
_, err = globalstate.EgoscaleClient.CreateDNSDomainRecord(ctx, account.CurrentAccount.DefaultZone, *domain.ID, &exo.DNSDomainRecord{
Name: &name,
Type: &rType,
Content: &content,
TTL: &ttl,
Priority: priority,
})
ctx := gContext
err = decorateAsyncOperations(fmt.Sprintf("Adding DNS record %q to %q...", rType, domain.UnicodeName), func() error {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

recordType, err := StringToDNSDomainRecordRequestType(rType)
if err != nil {
return fmt.Errorf("exoscale: error while get DNS record type: %w", err)
}

dnsDomainRecordRequest := v3.CreateDNSDomainRecordRequest{
Content: content,
Name: name,
Ttl: ttl,
Type: recordType,
}

if priority != nil {
dnsDomainRecordRequest.Priority = *priority
}

op, err := globalstate.EgoscaleV3Client.CreateDNSDomainRecord(ctx, domain.ID, dnsDomainRecordRequest)

mlec1 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf("exoscale: error while creating DNS record: %w", err)
}

_, err = globalstate.EgoscaleV3Client.Wait(ctx, op, v3.OperationStateSuccess)
if err != nil {
return fmt.Errorf("exoscale: error while waiting for DNS record creation: %w", err)
}

return nil
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

if err != nil {
return err
}

if !globalstate.Quiet {
fmt.Printf("Record %q was created successfully to %q\n", rType, *domain.UnicodeName)
fmt.Printf("Record %q was created successfully to %q\n", rType, domain.UnicodeName)
}

return nil
Expand Down
26 changes: 12 additions & 14 deletions cmd/dns_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exo "github.com/exoscale/egoscale/v2"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

func init() {
Expand All @@ -27,23 +25,23 @@ func init() {
}

func createDomain(domainName string) error {
var err error
domain := &exo.DNSDomain{}

ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
decorateAsyncOperation(fmt.Sprintf("Creating DNS domain %q...", domainName), func() {
domain, err = globalstate.EgoscaleClient.CreateDNSDomain(
ctx,
account.CurrentAccount.DefaultZone,
&exo.DNSDomain{UnicodeName: &domainName},
)
ctx := gContext

err := decorateAsyncOperations(fmt.Sprintf("Creating DNS domain %q...", domainName), func() error {
_, err := globalstate.EgoscaleV3Client.CreateDNSDomain(ctx, v3.CreateDNSDomainRequest{UnicodeName: domainName})
if err != nil {
return err
}

return nil
mlec1 marked this conversation as resolved.
Show resolved Hide resolved
})

if err != nil {
return err
}

if !globalstate.Quiet {
fmt.Printf("Domain %q was created successfully\n", *domain.UnicodeName)
fmt.Printf("Domain %q was created successfully\n", domainName)
}

return nil
Expand Down
27 changes: 16 additions & 11 deletions cmd/dns_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

func init() {
Expand Down Expand Up @@ -38,24 +37,30 @@ func deleteDomain(ident string, force bool) error {
return err
}

if !force && !askQuestion(fmt.Sprintf("Are you sure you want to delete %q domain?", *domain.UnicodeName)) {
if !force && !askQuestion(fmt.Sprintf("Are you sure you want to delete %q domain?", domain.UnicodeName)) {
return nil
}

ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
decorateAsyncOperation(fmt.Sprintf("Deleting DNS domain %q...", *domain.UnicodeName), func() {
err = globalstate.EgoscaleClient.DeleteDNSDomain(
ctx,
account.CurrentAccount.DefaultZone,
domain,
)
ctx := gContext
err = decorateAsyncOperations(fmt.Sprintf("Deleting DNS domain %q...", domain.UnicodeName), func() error {
op, err := globalstate.EgoscaleV3Client.DeleteDNSDomain(ctx, domain.ID)
if err != nil {
return fmt.Errorf("exoscale: error while deleting DNS domain: %w", err)
}

_, err = globalstate.EgoscaleV3Client.Wait(ctx, op, v3.OperationStateSuccess)
if err != nil {
return fmt.Errorf("exoscale: error while waiting DNS domain deletion: %w", err)
}

return nil
})
if err != nil {
return err
}

if !globalstate.Quiet {
fmt.Printf("Domain %q was deleted successfully\n", *domain.UnicodeName)
fmt.Printf("Domain %q was deleted successfully\n", domain.UnicodeName)
}

return nil
Expand Down
18 changes: 10 additions & 8 deletions cmd/dns_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (
"os"
"strings"

exoapi "github.com/exoscale/egoscale/v2/api"

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/table"
Expand Down Expand Up @@ -57,18 +54,23 @@ Supported output template annotations: %s`,
}

func listDomains(filters []string) (output.Outputter, error) {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, account.CurrentAccount.DefaultZone))
domains, err := globalstate.EgoscaleClient.ListDNSDomains(ctx, account.CurrentAccount.DefaultZone)
ctx := gContext
domains, err := globalstate.EgoscaleV3Client.ListDNSDomains(ctx)
if err != nil {
return nil, err
}

out := dnsListOutput{}

for _, d := range domains {
for _, d := range domains.DNSDomains {

// Convert v3.UUID to string using String() method, then get a pointer to it
// Don't know if it is best practice
idStr := d.ID.String() // Convert UUID to string

o := dnsListItemOutput{
ID: StrPtrFormatOutput(d.ID),
Name: StrPtrFormatOutput(d.UnicodeName),
ID: StrPtrFormatOutput(&idStr),
Name: StrPtrFormatOutput(&d.UnicodeName),
mlec1 marked this conversation as resolved.
Show resolved Hide resolved
}

if len(filters) == 0 {
Expand Down
Loading