-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add cdn operations * add docs * add tests fix doc fix flags for update * remove unused constant * fix default url * update docs * remove wrong constant string * fix typo in file name * add example * update filter names and split geo restrictions * update docs
- Loading branch information
1 parent
ceb6cf4
commit d979378
Showing
55 changed files
with
8,869 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
# Changelog | ||
|
||
## [v6.8.0] | ||
- Added support for CDN operations | ||
|
||
## [v6.7.8] (October 2024) | ||
|
||
### Added | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package cdn | ||
|
||
import ( | ||
"github.com/ionos-cloud/ionosctl/v6/commands/cdn/distribution" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/core" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func Command() *core.Command { | ||
cmd := &core.Command{ | ||
Command: &cobra.Command{ | ||
Use: "cdn", | ||
Short: "The sub-commands of the 'cdn' resource help manage CDN distributions", | ||
TraverseChildren: true, | ||
}, | ||
} | ||
cmd.AddCommand(distribution.Command()) | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package completer | ||
|
||
import ( | ||
"context" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/client" | ||
"github.com/ionos-cloud/ionosctl/v6/pkg/functional" | ||
cdn "github.com/ionos-cloud/sdk-go-cdn" | ||
) | ||
|
||
// DistributionsProperty returns a list of properties of all distributions matching the given filters | ||
func DistributionsProperty[V any](f func(cdn.Distribution) V, fs ...Filter) []V { | ||
recs, err := Distributions(fs...) | ||
if err != nil { | ||
return nil | ||
} | ||
return functional.Map(*recs.Items, f) | ||
} | ||
|
||
// Distributions returns all distributions matching the given filters | ||
func Distributions(fs ...Filter) (cdn.Distributions, error) { | ||
req := client.Must().CDNClient.DistributionsApi.DistributionsGet(context.Background()) | ||
for _, f := range fs { | ||
var err error | ||
req, err = f(req) | ||
if err != nil { | ||
return cdn.Distributions{}, err | ||
} | ||
} | ||
|
||
ls, _, err := req.Execute() | ||
if err != nil { | ||
return cdn.Distributions{}, err | ||
} | ||
return ls, nil | ||
} | ||
|
||
type Filter func(request cdn.ApiDistributionsGetRequest) (cdn.ApiDistributionsGetRequest, error) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package distribution | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/client" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/constants" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/core" | ||
"github.com/ionos-cloud/ionosctl/v6/pkg/pointer" | ||
"github.com/ionos-cloud/ionosctl/v6/pkg/uuidgen" | ||
cdn "github.com/ionos-cloud/sdk-go-cdn" | ||
"github.com/spf13/viper" | ||
"os" | ||
) | ||
|
||
func Create() *core.Command { | ||
cmd := core.NewCommand(context.Background(), nil, core.CommandBuilder{ | ||
Namespace: "cdn", | ||
Resource: "distribution", | ||
Verb: "create", | ||
Aliases: []string{"c", "post"}, | ||
ShortDesc: "Create a CDN distribution. Wiki: https://docs.ionos.com/cloud/network-services/cdn/dcd-how-tos/create-cdn-distribution", | ||
Example: "ionosctl cdn ds create --domain foo-bar.com --certificate-id id --routing-rules rules.json", | ||
PreCmdRun: func(c *core.PreCommandConfig) error { | ||
if err := core.CheckRequiredFlagsSets(c.Command, c.NS, | ||
[]string{constants.FlagCDNDistributionDomain, constants.FlagCDNDistributionRoutingRules}, | ||
[]string{constants.FlagCDNDistributionRoutingRulesExample}); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}, | ||
CmdRun: func(c *core.CommandConfig) error { | ||
if viper.GetBool(core.GetFlagName(c.NS, constants.FlagCDNDistributionRoutingRulesExample)) { | ||
fmt.Fprintf(c.Command.Command.OutOrStdout(), RoutingRuleExample) | ||
return nil | ||
} | ||
|
||
input := &cdn.DistributionProperties{} | ||
if err := setPropertiesFromFlags(c, input); err != nil { | ||
return err | ||
} | ||
|
||
id := uuidgen.Must() | ||
res, _, err := client.Must().CDNClient.DistributionsApi.DistributionsPut(context.Background(), id). | ||
DistributionUpdate(cdn.DistributionUpdate{ | ||
Id: &id, | ||
Properties: input, | ||
}).Execute() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return printDistribution(c, res) | ||
}, | ||
InitClient: true, | ||
}) | ||
|
||
cmd.Command.SilenceUsage = true | ||
cmd.Command.Flags().SortFlags = false | ||
return addDistributionCreateFlags(cmd) | ||
} | ||
|
||
func addDistributionCreateFlags(cmd *core.Command) *core.Command { | ||
cmd.AddStringFlag(constants.FlagCDNDistributionDomain, "", "", "The domain of the distribution") | ||
cmd.AddStringFlag(constants.FlagCDNDistributionCertificateID, "", "", "The ID of the certificate") | ||
cmd.AddStringFlag(constants.FlagCDNDistributionRoutingRules, "", "", "The routing rules of the distribution. JSON string or file path of routing rules") | ||
cmd.AddBoolFlag(constants.FlagCDNDistributionRoutingRulesExample, "", false, "Print an example of routing rules") | ||
return cmd | ||
} | ||
|
||
func setPropertiesFromFlags(c *core.CommandConfig, p *cdn.DistributionProperties) error { | ||
if fn := core.GetFlagName(c.NS, constants.FlagCDNDistributionDomain); viper.IsSet(fn) { | ||
p.Domain = pointer.From(viper.GetString(fn)) | ||
} | ||
|
||
if fn := core.GetFlagName(c.NS, constants.FlagCDNDistributionCertificateID); viper.IsSet(fn) { | ||
p.CertificateId = pointer.From(viper.GetString(fn)) | ||
} | ||
|
||
if fn := core.GetFlagName(c.NS, constants.FlagCDNDistributionRoutingRules); viper.IsSet(fn) { | ||
rr := viper.GetString(fn) | ||
data, err := getRoutingRulesData(rr) | ||
if err != nil { | ||
return fmt.Errorf("error reading routing rules file: %s", err) | ||
} | ||
|
||
rules, err := getRoutingRulesFromJSON(data) | ||
if err != nil { | ||
return fmt.Errorf("error parsing routing rules: %s", err) | ||
} | ||
p.RoutingRules = rules | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func getRoutingRulesFromJSON(data []byte) (*[]cdn.RoutingRule, error) { | ||
var rr []cdn.RoutingRule | ||
err := json.Unmarshal(data, &rr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &rr, nil | ||
} | ||
|
||
func getRoutingRulesData(input string) ([]byte, error) { | ||
switch _, err := os.Stat(input); { | ||
case err == nil: | ||
return os.ReadFile(input) | ||
case os.IsNotExist(err): | ||
return []byte(input), nil | ||
default: | ||
return nil, err | ||
} | ||
} | ||
|
||
const RoutingRuleExample = ` | ||
[ | ||
{ | ||
"prefix": "/api", | ||
"scheme": "http/https", | ||
"upstream": { | ||
"caching": true, | ||
"geoRestrictions": { | ||
"allowList": ["CN", "RU"] | ||
}, | ||
"host": "clitest.example.com", | ||
"rateLimitClass": "R500", | ||
"sniMode": "distribution", | ||
"waf": true | ||
} | ||
}, | ||
{ | ||
"prefix": "/api2", | ||
"scheme": "http/https", | ||
"upstream": { | ||
"caching": false, | ||
"geoRestrictions": { | ||
"blockList": ["CN", "RU"] | ||
}, | ||
"host": "server2.example.com", | ||
"rateLimitClass": "R10", | ||
"sniMode": "origin", | ||
"waf": false | ||
} | ||
} | ||
] | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package distribution | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/ionos-cloud/ionosctl/v6/commands/cdn/completer" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/client" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/constants" | ||
"github.com/ionos-cloud/ionosctl/v6/pkg/confirm" | ||
cdn "github.com/ionos-cloud/sdk-go-cdn" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
|
||
"github.com/ionos-cloud/ionosctl/v6/internal/core" | ||
) | ||
|
||
func Delete() *core.Command { | ||
cmd := core.NewCommand(context.Background(), nil, core.CommandBuilder{ | ||
Namespace: "cdn", | ||
Resource: "distribution", | ||
Verb: "delete", | ||
Aliases: []string{"del", "d"}, | ||
ShortDesc: "Delete a distribution", | ||
Example: `ionosctl cdn ds delete --distribution-id ID`, | ||
PreCmdRun: func(c *core.PreCommandConfig) error { | ||
if err := core.CheckRequiredFlags(c.Command, c.NS, constants.FlagCDNDistributionID); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}, | ||
CmdRun: func(c *core.CommandConfig) error { | ||
distributionID := viper.GetString(core.GetFlagName(c.NS, constants.FlagCDNDistributionID)) | ||
d, _, err := client.Must().CDNClient.DistributionsApi.DistributionsFindById(context.Background(), distributionID).Execute() | ||
if err != nil { | ||
return fmt.Errorf("distribution not found: %w", err) | ||
} | ||
|
||
yes := confirm.FAsk(c.Command.Command.InOrStdin(), fmt.Sprintf("Are you sure you want to delete distribution %s for domain %s", *d.Id, *d.Properties.Domain), | ||
viper.GetBool(constants.ArgForce)) | ||
if !yes { | ||
return fmt.Errorf("user cancelled deletion") | ||
} | ||
|
||
_, err = client.Must().CDNClient.DistributionsApi.DistributionsDelete(context.Background(), *d.Id).Execute() | ||
return err | ||
}, | ||
InitClient: true, | ||
}) | ||
|
||
cmd.AddStringFlag(constants.FlagCDNDistributionID, constants.FlagIdShort, "", "The ID of the distribution you want to retrieve", core.RequiredFlagOption()) | ||
_ = cmd.Command.RegisterFlagCompletionFunc(constants.FlagCDNDistributionID, func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return completer.DistributionsProperty(func(r cdn.Distribution) string { | ||
return *r.Id | ||
}), cobra.ShellCompDirectiveNoFileComp | ||
}) | ||
|
||
cmd.Command.SilenceUsage = true | ||
cmd.Command.Flags().SortFlags = false | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package distribution | ||
|
||
import ( | ||
"github.com/ionos-cloud/ionosctl/v6/commands/cdn/distribution/routingrules" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/constants" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/core" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/printer/tabheaders" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
allCols = []string{"Id", "Domain", "CertificateId", "State"} | ||
defaultCols = []string{"Id", "Domain", "CertificateId", "State"} | ||
) | ||
|
||
func Command() *core.Command { | ||
cmd := &core.Command{ | ||
Command: &cobra.Command{ | ||
Use: "distribution", | ||
Short: "The sub-commands of 'ionosctl cdn distribution' allow you to manage CDN distributions", | ||
Aliases: []string{"ds"}, | ||
TraverseChildren: true, | ||
}, | ||
} | ||
cmd.Command.PersistentFlags().StringSlice(constants.ArgCols, nil, tabheaders.ColsMessage(allCols)) | ||
_ = cmd.Command.RegisterFlagCompletionFunc(constants.ArgCols, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return allCols, cobra.ShellCompDirectiveNoFileComp | ||
}) | ||
|
||
cmd.AddCommand(List()) | ||
cmd.AddCommand(FindByID()) | ||
cmd.AddCommand(Delete()) | ||
cmd.AddCommand(Create()) | ||
cmd.AddCommand(Update()) | ||
cmd.AddCommand(routingrules.Root()) | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package distribution | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/ionos-cloud/ionosctl/v6/commands/cdn/completer" | ||
cdn "github.com/ionos-cloud/sdk-go-cdn" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/ionos-cloud/ionosctl/v6/internal/client" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/constants" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/core" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/printer/json2table/jsonpaths" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/printer/jsontabwriter" | ||
"github.com/ionos-cloud/ionosctl/v6/internal/printer/tabheaders" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
func FindByID() *core.Command { | ||
cmd := core.NewCommand(context.Background(), nil, core.CommandBuilder{ | ||
Namespace: "cdn", | ||
Resource: "distribution", | ||
Verb: "get", | ||
Aliases: []string{"g"}, | ||
ShortDesc: "Retrieve a distribution", | ||
Example: "ionosctl cdn ds get --distribution-id ID", | ||
PreCmdRun: func(c *core.PreCommandConfig) error { | ||
if err := core.CheckRequiredFlags(c.Command, c.NS, constants.FlagCDNDistributionID); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}, | ||
CmdRun: func(c *core.CommandConfig) error { | ||
distributionID := viper.GetString(core.GetFlagName(c.NS, constants.FlagCDNDistributionID)) | ||
r, _, err := client.Must().CDNClient.DistributionsApi.DistributionsFindById(context.Background(), | ||
distributionID, | ||
).Execute() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cols, _ := c.Command.Command.Flags().GetStringSlice(constants.ArgCols) | ||
out, err := jsontabwriter.GenerateOutput("", jsonpaths.CDNDistribution, r, | ||
tabheaders.GetHeadersAllDefault(defaultCols, cols)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Fprintf(c.Command.Command.OutOrStdout(), out) | ||
return nil | ||
}, | ||
InitClient: true, | ||
}) | ||
cmd.AddStringFlag(constants.FlagCDNDistributionID, constants.FlagIdShort, "", "The ID of the distribution you want to retrieve", core.RequiredFlagOption()) | ||
_ = cmd.Command.RegisterFlagCompletionFunc(constants.FlagCDNDistributionID, func(c *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return completer.DistributionsProperty(func(r cdn.Distribution) string { | ||
return *r.Id | ||
}), cobra.ShellCompDirectiveNoFileComp | ||
}) | ||
cmd.Command.SilenceUsage = true | ||
cmd.Command.Flags().SortFlags = false | ||
return cmd | ||
} |
Oops, something went wrong.