Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions messages/dnssec/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dnssec

import (
"errors"
)

var (
ErrorGetDNSSEC = errors.New("Failed to describe the DNSSEC: %s. Check your settings and try again. If the error persists, contact Azion support.")
ErrorUpdateDNSSEC = errors.New("Failed to update the DNSSEC: %s. Check your settings and try again. If the error persists, contact Azion support.")

ErrorConvertIdZone = errors.New("The DNS zone ID you provided is invalid. The value must be an integer. You may run the 'azion list dns-zone' command to check your DNS zones' IDs")
ErrorConvertEnabled = errors.New("The value provided for '--enabled' is invalid. The value must be a boolean (true or false)")
)
32 changes: 32 additions & 0 deletions messages/dnssec/messages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dnssec

var (
// [ dnssec ]
DNSSECUsage = "dnssec"
DNSSECShortDescription = "Manages DNSSEC for an Intelligent DNS zone"
DNSSECLongDescription = "DNSSEC adds cryptographic signatures to your Intelligent DNS zone records, protecting against DNS spoofing and cache poisoning attacks."
DNSSECFlagHelp = "Displays more information about the dnssec command"

// [ describe ]
DNSSECDescribeUsage = "describe --zone-id <zone_id> [flags]"
DNSSECDescribeShortDescription = "Returns the DNSSEC information of a specific DNS zone"
DNSSECDescribeLongDescription = "Returns the DNSSEC information of a specific DNS zone, informed through the flag '--zone-id', in detail"
DNSSECDescribeFlagOut = "Exports the output of the subcommand 'describe' to the given file path <file_path/file_name.ext>"
DNSSECDescribeFlagFormat = "Changes the output format passing the json value to the flag. Example '--format json'"
DNSSECDescribeHelpFlag = "Displays more information about the describe subcommand"
DNSSECDescribeAskInputZoneID = "Enter the ID of the DNS zone whose DNSSEC you wish to describe:"

// [ update ]
DNSSECUpdateUsage = "update --zone-id <zone_id> --enabled <bool> [flags]"
DNSSECUpdateShortDescription = "Updates the DNSSEC of a DNS zone"
DNSSECUpdateLongDescription = "Enables or disables DNSSEC for a DNS zone based on the given attributes"
DNSSECUpdateFlagEnabled = "Whether DNSSEC should be enabled for the DNS zone"
DNSSECUpdateFlagIn = "Path to a JSON file containing the attributes of the DNSSEC that will be updated; you can use - for reading from stdin"
DNSSECUpdateOutputSuccess = "DNSSEC of DNS zone %d was updated\n"
DNSSECUpdateHelpFlag = "Displays more information about the update subcommand"
DNSSECUpdateAskInputZoneID = "Enter the ID of the DNS zone whose DNSSEC you wish to update:"
DNSSECUpdateAskInputEnabled = "Enter whether DNSSEC should be enabled (true/false):"

// [ flags ]
DNSSECFlagZoneID = "Unique identifier for a DNS zone. The '--zone-id' flag is required"
)
29 changes: 29 additions & 0 deletions pkg/api/dnssec/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dnssec

import (
"net/http"
"time"

"github.com/aziontech/azion-cli/pkg/cmd/version"
sdk "github.com/aziontech/azionapi-v4-go-sdk-dev/azion-api"
)

type Client struct {
apiClient *sdk.APIClient
}

func NewClient(c *http.Client, url string, token string) *Client {
conf := sdk.NewConfiguration()
conf.HTTPClient = c
conf.AddDefaultHeader("Authorization", "token "+token)
conf.AddDefaultHeader("Accept", "application/json")
conf.UserAgent = "Azion_CLI/" + version.BinVersion
conf.Servers = sdk.ServerConfigurations{
{URL: url},
}
conf.HTTPClient.Timeout = 50 * time.Second

return &Client{
apiClient: sdk.NewAPIClient(conf),
}
}
49 changes: 49 additions & 0 deletions pkg/api/dnssec/dnssec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package dnssec

import (
"context"

"github.com/aziontech/azion-cli/pkg/logger"
"github.com/aziontech/azion-cli/utils"
sdk "github.com/aziontech/azionapi-v4-go-sdk-dev/azion-api"
"go.uber.org/zap"
)

func (c *Client) Get(ctx context.Context, zoneID int64) (sdk.DNSSEC, error) {
logger.Debug("Get DNSSEC")

resp, httpResp, err := c.apiClient.DNSDNSSECAPI.
RetrieveDnssec(ctx, zoneID).
Execute()
if err != nil {
logger.Debug("Error while getting the DNSSEC", zap.Any("ID", zoneID), zap.Error(err))
errBody, err := utils.LogAndRewindBodyV4(httpResp)
if err != nil {
return sdk.DNSSEC{}, err
}

return sdk.DNSSEC{}, utils.ErrorPerStatusCodeV4(errBody, httpResp, err)
}

return resp.GetData(), nil
}

func (c *Client) Update(ctx context.Context, req sdk.PatchedDNSSECRequest, zoneID int64) (sdk.DNSSEC, error) {
logger.Debug("Update DNSSEC")

request := c.apiClient.DNSDNSSECAPI.
PartialUpdateDnssec(ctx, zoneID).
PatchedDNSSECRequest(req)
resp, httpResp, err := request.Execute()
if err != nil {
logger.Debug("Error while updating the DNSSEC", zap.Any("ID", zoneID), zap.Error(err))
errBody, err := utils.LogAndRewindBodyV4(httpResp)
if err != nil {
return sdk.DNSSEC{}, err
}

return sdk.DNSSEC{}, utils.ErrorPerStatusCodeV4(errBody, httpResp, err)
}

return resp.GetData(), nil
}
2 changes: 2 additions & 0 deletions pkg/cmd/describe/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
digitalcertificate "github.com/aziontech/azion-cli/pkg/cmd/describe/digital_certificate"
dnsRecord "github.com/aziontech/azion-cli/pkg/cmd/describe/dns_record"
dnsZone "github.com/aziontech/azion-cli/pkg/cmd/describe/dns_zone"
dnssec "github.com/aziontech/azion-cli/pkg/cmd/describe/dnssec"
firewall "github.com/aziontech/azion-cli/pkg/cmd/describe/firewall"
firewallinstance "github.com/aziontech/azion-cli/pkg/cmd/describe/firewall_instance"
firewallrules "github.com/aziontech/azion-cli/pkg/cmd/describe/firewall_rules"
Expand Down Expand Up @@ -58,6 +59,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(deviceGroups.NewCmd(f))
cmd.AddCommand(dnsZone.NewCmd(f))
cmd.AddCommand(dnsRecord.NewCmd(f))
cmd.AddCommand(dnssec.NewCmd(f))
cmd.AddCommand(function.NewCmd(f))
cmd.AddCommand(variables.NewCmd(f))
cmd.AddCommand(edgeStorage.NewCmd(f))
Expand Down
104 changes: 104 additions & 0 deletions pkg/cmd/describe/dnssec/dnssec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package dnssec

import (
"context"
"fmt"
"path/filepath"
"strconv"

"github.com/MakeNowJust/heredoc"
"go.uber.org/zap"

msg "github.com/aziontech/azion-cli/messages/dnssec"
api "github.com/aziontech/azion-cli/pkg/api/dnssec"
"github.com/aziontech/azion-cli/pkg/cmdutil"
"github.com/aziontech/azion-cli/pkg/contracts"
"github.com/aziontech/azion-cli/pkg/iostreams"
"github.com/aziontech/azion-cli/pkg/logger"
"github.com/aziontech/azion-cli/pkg/output"
"github.com/aziontech/azion-cli/utils"
sdk "github.com/aziontech/azionapi-v4-go-sdk-dev/azion-api"
"github.com/spf13/cobra"
)

var zoneID int64

type DescribeCmd struct {
Io *iostreams.IOStreams
AskInput func(string) (string, error)
Get func(context.Context, int64) (sdk.DNSSEC, error)
}

func NewDescribeCmd(f *cmdutil.Factory) *DescribeCmd {
return &DescribeCmd{
Io: f.IOStreams,
AskInput: func(prompt string) (string, error) {
return utils.AskInput(prompt)
},
Get: func(ctx context.Context, id int64) (sdk.DNSSEC, error) {
client := api.NewClient(f.HttpClient, f.Config.GetString("api_v4_url"), f.Config.GetString("token"))
return client.Get(ctx, id)
},
}
}

func NewCobraCmd(describe *DescribeCmd, f *cmdutil.Factory) *cobra.Command {
opts := &contracts.DescribeOptions{}
cobraCmd := &cobra.Command{
Use: msg.DNSSECUsage,
Short: msg.DNSSECDescribeShortDescription,
Long: msg.DNSSECDescribeLongDescription,
SilenceUsage: true,
SilenceErrors: true,
Example: heredoc.Doc(`
$ azion describe dnssec --zone-id 107313
$ azion describe dnssec --zone-id 107313 --format json
$ azion describe dnssec --zone-id 107313 --out "./tmp/test.json"
`),
RunE: func(cmd *cobra.Command, args []string) error {
if !cmd.Flags().Changed("zone-id") {
answer, err := describe.AskInput(msg.DNSSECDescribeAskInputZoneID)
if err != nil {
return err
}

num, err := strconv.ParseInt(answer, 10, 64)
if err != nil {
logger.Debug("Error while converting answer to int64", zap.Error(err))
return msg.ErrorConvertIdZone
}

zoneID = num
}

ctx := context.Background()
resp, err := describe.Get(ctx, zoneID)
if err != nil {
return fmt.Errorf(msg.ErrorGetDNSSEC.Error(), err)
}

fields := make(map[string]string, 0)
fields["Enabled"] = "Enabled"
fields["Status"] = "Status"

describeOut := output.DescribeOutput{
GeneralOutput: output.GeneralOutput{
Out: f.IOStreams.Out,
Msg: filepath.Clean(opts.OutPath),
Flags: f.Flags,
},
Fields: fields,
Values: &resp,
}
return output.Print(&describeOut)
},
}

cobraCmd.Flags().Int64Var(&zoneID, "zone-id", 0, msg.DNSSECFlagZoneID)
cobraCmd.Flags().BoolP("help", "h", false, msg.DNSSECDescribeHelpFlag)
return cobraCmd
}

func NewCmd(f *cmdutil.Factory) *cobra.Command {
return NewCobraCmd(NewDescribeCmd(f), f)
}
71 changes: 71 additions & 0 deletions pkg/cmd/describe/dnssec/dnssec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package dnssec

import (
"net/http"
"testing"

"github.com/aziontech/azion-cli/pkg/httpmock"
"github.com/aziontech/azion-cli/pkg/logger"
"github.com/aziontech/azion-cli/pkg/testutils"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
)

func TestDescribe(t *testing.T) {
logger.New(zapcore.DebugLevel)

tests := []struct {
name string
request httpmock.Matcher
response httpmock.Responder
args []string
expectErr bool
mockInput func(string) (string, error)
}{
{
name: "describe DNSSEC",
request: httpmock.REST("GET", "workspace/dns/zones/1337/dnssec"),
response: httpmock.JSONFromFile("./fixtures/response.json"),
args: []string{"--zone-id", "1337"},
expectErr: false,
},
{
name: "describe DNSSEC - no zone id, ask input",
request: httpmock.REST("GET", "workspace/dns/zones/1337/dnssec"),
response: httpmock.JSONFromFile("./fixtures/response.json"),
expectErr: false,
mockInput: func(s string) (string, error) {
return "1337", nil
},
},
{
name: "not found",
request: httpmock.REST("GET", "workspace/dns/zones/1234/dnssec"),
response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"),
args: []string{"--zone-id", "1234"},
expectErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mock := &httpmock.Registry{}
mock.Register(tt.request, tt.response)

f, _, _ := testutils.NewFactory(mock)
descCmd := NewDescribeCmd(f)
if tt.mockInput != nil {
descCmd.AskInput = tt.mockInput
}
cmd := NewCobraCmd(descCmd, f)
cmd.SetArgs(tt.args)

err := cmd.Execute()
if tt.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
19 changes: 19 additions & 0 deletions pkg/cmd/describe/dnssec/fixtures/response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"state": "executed",
"data": {
"enabled": true,
"status": "active",
"delegation_signer": {
"algorithm_type": {
"id": 13,
"slug": "ecdsap256sha256"
},
"digest": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"digest_type": {
"id": 2,
"slug": "sha256"
},
"key_tag": 12345
}
}
}
Loading
Loading