diff --git a/cli/domain/create.go b/cli/domain/create.go new file mode 100644 index 000000000..c309de9af --- /dev/null +++ b/cli/domain/create.go @@ -0,0 +1,135 @@ +package domain + +import ( + "errors" + "fmt" + "strconv" + "time" + + abraFormatter "coopcloud.tech/abra/cli/formatter" + "coopcloud.tech/abra/cli/internal" + gandiPkg "coopcloud.tech/abra/pkg/dns/gandi" + "github.com/libdns/gandi" + "github.com/libdns/libdns" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" +) + +// DomainCreateCommand lists domains. +var DomainCreateCommand = &cli.Command{ + Name: "create", + Usage: "Create a new domain record", + Aliases: []string{"c"}, + ArgsUsage: " [] []", + Flags: []cli.Flag{ + internal.DNSProviderFlag, + }, + Description: ` +This command creates a new domain name record for a specific zone. + +You must specify a zone (e.g. example.com) under which your domain name records +are listed. This zone must already be created on your provider account. + +Examples: + + abra domain create -p gandi foo.com A myapp 192.168.178.44 + +Which means you can then deploy an app against "myapp.foo.com" successfully. +`, + Action: func(c *cli.Context) error { + zone := c.Args().First() + if zone == "" { + internal.ShowSubcommandHelpAndError(c, errors.New("no zone provided")) + } + + recordType := c.Args().Get(1) + recordName := c.Args().Get(2) + recordValue := c.Args().Get(3) + recordTTL := c.Args().Get(4) + recordPriority := c.Args().Get(5) + + if recordType == "" { + internal.ShowSubcommandHelpAndError(c, errors.New("no type provided")) + } + if recordName == "" { + internal.ShowSubcommandHelpAndError(c, errors.New("no name provided")) + } + if recordValue == "" { + internal.ShowSubcommandHelpAndError(c, errors.New("no value provided")) + } + + if recordTTL == "" { + recordTTL = "86400" + } + + if recordType == "MX" || recordType == "SRV" || recordType == "URI" { + if recordPriority == "" { + logrus.Fatal("record priority must be set when using MX/SRV/URI records") + } + } + + var err error + var provider gandi.Provider + switch internal.DNSProvider { + case "gandi": + provider, err = gandiPkg.New() + if err != nil { + logrus.Fatal(err) + } + default: + logrus.Fatalf("'%s' is not a supported DNS provider", internal.DNSProvider) + } + + ttl, err := strconv.Atoi(recordTTL) + if err != nil { + logrus.Fatal(err) + } + + record := libdns.Record{ + Type: recordType, + Name: recordName, + Value: recordValue, + TTL: time.Duration(ttl), + } + + if recordType == "MX" || recordType == "SRV" || recordType == "URI" { + priority, err := strconv.Atoi(recordPriority) + if err != nil { + logrus.Fatal(err) + } + record.Priority = priority + } + + createdRecords, err := provider.SetRecords( + c.Context, + zone, + []libdns.Record{record}, + ) + + if len(createdRecords) == 0 { + logrus.Fatal("provider library reports no record created?") + } + + createdRecord := createdRecords[0] + + tableCol := []string{"type", "name", "value", "TTL", "priority"} + table := abraFormatter.CreateTable(tableCol) + + value := createdRecord.Value + if len(createdRecord.Value) > 30 { + value = fmt.Sprintf("%s...", createdRecord.Value[:30]) + } + + table.Append([]string{ + createdRecord.Type, + createdRecord.Name, + value, + createdRecord.TTL.String(), + strconv.Itoa(createdRecord.Priority), + }) + + table.Render() + + return nil + }, +} diff --git a/cli/domain/domain.go b/cli/domain/domain.go index 0094d9b57..06fe05e5c 100644 --- a/cli/domain/domain.go +++ b/cli/domain/domain.go @@ -32,5 +32,6 @@ allows to implement new provider support easily. `, Subcommands: []*cli.Command{ DomainListCommand, + DomainCreateCommand, }, }