Skip to content

Commit aabc8b3

Browse files
committed
Merge with master
2 parents f1f5602 + 3cb8c02 commit aabc8b3

10 files changed

Lines changed: 673 additions & 0 deletions

File tree

plugin/commands/cdn/cdn.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ func SetupCobraCommands(sl *metadata.SoftlayerCommand) *cobra.Command {
1919
cobraCmd.AddCommand(NewOriginRemoveCommand(sl).Command)
2020
cobraCmd.AddCommand(NewDetailCommand(sl).Command)
2121
cobraCmd.AddCommand(NewEditCommand(sl).Command)
22+
cobraCmd.AddCommand(NewOriginListCommand(sl).Command)
2223
cobraCmd.AddCommand(NewCreateCommand(sl).Command)
24+
cobraCmd.AddCommand(NewOriginAddCommand(sl).Command)
2325
return cobraCmd
2426
}
2527

plugin/commands/cdn/cdn_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ var availableCommands = []string{
2323
"delete",
2424
"edit",
2525
"list",
26+
"origin-list",
2627
"create",
28+
"origin-add",
2729
}
2830

2931
// This test suite exists to make sure commands don't get accidently removed from the actionBindings

plugin/commands/cdn/origin_add.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package cdn
2+
3+
import (
4+
"regexp"
5+
6+
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/terminal"
7+
"github.com/softlayer/softlayer-go/datatypes"
8+
"github.com/spf13/cobra"
9+
10+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/errors"
11+
. "github.ibm.com/SoftLayer/softlayer-cli/plugin/i18n"
12+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/managers"
13+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/metadata"
14+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/utils"
15+
)
16+
17+
type OriginAddCommand struct {
18+
*metadata.SoftlayerCommand
19+
CdnManager managers.CdnManager
20+
Command *cobra.Command
21+
Header string
22+
Path string
23+
OriginHost string
24+
OriginType string
25+
Http int
26+
Https int
27+
CacheKey string
28+
Optimize string
29+
DynamicPath string
30+
DynamicPrefetch bool
31+
DynamicCompression bool
32+
BuckeName string
33+
fileExtension string
34+
}
35+
36+
func NewOriginAddCommand(sl *metadata.SoftlayerCommand) *OriginAddCommand {
37+
thisCmd := &OriginAddCommand{
38+
SoftlayerCommand: sl,
39+
CdnManager: managers.NewCdnManager(sl.Session),
40+
}
41+
cobraCmd := &cobra.Command{
42+
Use: "origin-add " + T("IDENTIFIER"),
43+
Short: T("Create an origin path for an existing CDN mapping."),
44+
Long: T(`${COMMAND_NAME} sl cdn origin-add
45+
Example:
46+
${COMMAND_NAME} sl cdn origin-add --origin 123.123.123.123 --path /example/videos --http 80`),
47+
Args: metadata.OneArgs,
48+
RunE: func(cmd *cobra.Command, args []string) error {
49+
return thisCmd.Run(args)
50+
},
51+
}
52+
cobraCmd.Flags().StringVar(&thisCmd.Header, "header", "", T("The edge server uses the host header in the HTTP header to communicate with the Origin host. It defaults to Hostname."))
53+
cobraCmd.Flags().StringVar(&thisCmd.Path, "path", "", T("Give a path relative to the domain provided, which can be used to reach this Origin. For example, 'articles/video' => 'www.example.com/articles/video [required]"))
54+
cobraCmd.Flags().StringVar(&thisCmd.OriginHost, "origin", "", T("Your server IP address or hostname. [required]"))
55+
cobraCmd.Flags().StringVar(&thisCmd.OriginType, "origin-type", "server", T("The origin type. [Permit: server, storage] Note: If OriginType is storage then OriginHost is take as Endpoint."))
56+
cobraCmd.Flags().IntVar(&thisCmd.Http, "http", 0, T("Http port. [http or https is required]"))
57+
cobraCmd.Flags().IntVar(&thisCmd.Https, "https", 0, T("Https port. [http or https is required]"))
58+
cobraCmd.Flags().StringVar(&thisCmd.CacheKey, "cache-key", "include-all", T("Cache query rules with the following formats: 'include-all', 'ignore-all', 'include: <query-names>', 'ignore: <query-names>'. example <query-names> = 'uuid=1234567 issue=important'."))
59+
cobraCmd.Flags().StringVar(&thisCmd.Optimize, "optimize", "web", T("Performance configuration. [Permit: web, video, file, dynamic]"))
60+
cobraCmd.Flags().StringVar(&thisCmd.DynamicPath, "dynamic-path", "", T("The path that Akamai edge servers periodically fetch the test object from. example = /detection-test-object.html"))
61+
cobraCmd.Flags().BoolVar(&thisCmd.DynamicPrefetch, "prefetching", true, T("Enable or disable the embedded object prefetching feature."))
62+
cobraCmd.Flags().BoolVar(&thisCmd.DynamicCompression, "compression", true, T("Enable or disable compression of JPEG images for requests over certain network conditions."))
63+
cobraCmd.Flags().StringVar(&thisCmd.BuckeName, "bucket-name", "", T("Bucket name."))
64+
cobraCmd.Flags().StringVar(&thisCmd.fileExtension, "file-extensions", "", T("Specify the file extensions that can be stored on the CDN service, separated by commas. For example, 'jpg, pdf, jpeg, png' is a valid list. Leave the flag empty to allow all extensions."))
65+
66+
//#nosec G104 -- This is a false positive
67+
cobraCmd.MarkFlagRequired("path")
68+
//#nosec G104 -- This is a false positive
69+
cobraCmd.MarkFlagRequired("origin")
70+
thisCmd.Command = cobraCmd
71+
return thisCmd
72+
}
73+
74+
func (cmd *OriginAddCommand) Run(args []string) error {
75+
uniqueId := args[0]
76+
77+
if cmd.Http == 0 && cmd.Https == 0 {
78+
return errors.NewMissingInputError(T("http or https"))
79+
}
80+
81+
if cmd.OriginType != "server" && cmd.OriginType != "storage" {
82+
return errors.NewInvalidUsageError(T("--origintype"))
83+
}
84+
85+
if cmd.Optimize != "web" && cmd.Optimize != "video" && cmd.Optimize != "file" && cmd.Optimize != "dynamic" {
86+
return errors.NewInvalidUsageError(T("--optimize"))
87+
}
88+
89+
permitCacheKey := regexp.MustCompile(`^(ignore|include): \w+`)
90+
if cmd.CacheKey != "ignore-all" && cmd.CacheKey != "include-all" && !permitCacheKey.MatchString(cmd.CacheKey) {
91+
return errors.NewInvalidUsageError(T("--cache-key"))
92+
}
93+
94+
if cmd.OriginType == "storage" && cmd.BuckeName == "" {
95+
return errors.NewInvalidUsageError(T("--bucket-name can not be empty"))
96+
}
97+
98+
outputFormat := cmd.GetOutputFlag()
99+
100+
newOrigin, err := cmd.CdnManager.OriginAddCdn(uniqueId, cmd.Header, cmd.Path, cmd.OriginHost, cmd.OriginType, cmd.Http, cmd.Https, cmd.CacheKey, cmd.Optimize, cmd.DynamicPath, cmd.DynamicPrefetch, cmd.DynamicCompression, cmd.BuckeName, cmd.fileExtension)
101+
if err != nil {
102+
return errors.NewAPIError(T("Failed to create a Origin."), err.Error(), 2)
103+
}
104+
105+
PrintNewOrigin(cmd.UI, newOrigin, outputFormat)
106+
return nil
107+
}
108+
109+
func PrintNewOrigin(ui terminal.UI, cdn []datatypes.Container_Network_CdnMarketplace_Configuration_Mapping_Path, outputFormat string) {
110+
table := ui.Table([]string{
111+
T("Name"),
112+
T("Value"),
113+
})
114+
if len(cdn) > 0 {
115+
table.Add(T("CDN Unique ID"), utils.FormatStringPointer(cdn[0].MappingUniqueId))
116+
if cdn[0].BucketName != nil {
117+
table.Add(T("Bucket Name"), utils.FormatStringPointer(cdn[0].BucketName))
118+
}
119+
if cdn[0].FileExtension != nil {
120+
table.Add(T("File Extension"), utils.FormatStringPointer(cdn[0].FileExtension))
121+
}
122+
table.Add(T("Header"), utils.FormatStringPointer(cdn[0].Header))
123+
table.Add(T("Path"), utils.FormatStringPointer(cdn[0].Path))
124+
table.Add(T("Origin"), utils.FormatStringPointer(cdn[0].Origin))
125+
table.Add(T("Origin Type"), utils.FormatStringPointer(cdn[0].OriginType))
126+
table.Add(T("Http Port"), utils.FormatIntPointer(cdn[0].HttpPort))
127+
table.Add(T("Https Port"), utils.FormatIntPointer(cdn[0].HttpsPort))
128+
table.Add(T("Cache Key Rule"), utils.FormatStringPointer(cdn[0].CacheKeyQueryRule))
129+
table.Add(T("Performance Configuration"), utils.FormatStringPointer(cdn[0].PerformanceConfiguration))
130+
table.Add(T("Status"), utils.FormatStringPointer(cdn[0].Status))
131+
}
132+
utils.PrintTable(ui, table, outputFormat)
133+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package cdn_test
2+
3+
import (
4+
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers/terminal"
5+
. "github.com/onsi/ginkgo"
6+
. "github.com/onsi/gomega"
7+
"github.com/softlayer/softlayer-go/session"
8+
9+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/commands/cdn"
10+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/metadata"
11+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/testhelpers"
12+
)
13+
14+
var _ = Describe("Cdn origin add", func() {
15+
var (
16+
fakeUI *terminal.FakeUI
17+
cliCommand *cdn.OriginAddCommand
18+
fakeSession *session.Session
19+
slCommand *metadata.SoftlayerCommand
20+
)
21+
BeforeEach(func() {
22+
fakeUI = terminal.NewFakeUI()
23+
fakeSession = testhelpers.NewFakeSoftlayerSession([]string{})
24+
slCommand = metadata.NewSoftlayerCommand(fakeUI, fakeSession)
25+
cliCommand = cdn.NewOriginAddCommand(slCommand)
26+
cliCommand.Command.PersistentFlags().Var(cliCommand.OutputFlag, "output", "--output=JSON for json output.")
27+
})
28+
29+
Describe("Cdn origin add", func() {
30+
Context("Cdn origin add, Invalid Usage", func() {
31+
It("Set command with an invalid output option", func() {
32+
err := testhelpers.RunCobraCommand(cliCommand.Command, "--output=xml")
33+
Expect(err).To(HaveOccurred())
34+
Expect(err.Error()).To(ContainSubstring("Incorrect Usage: Invalid output format, only JSON is supported now."))
35+
})
36+
It("Set command without id", func() {
37+
err := testhelpers.RunCobraCommand(cliCommand.Command)
38+
Expect(err).To(HaveOccurred())
39+
Expect(err.Error()).To(ContainSubstring("Incorrect Usage: This command requires one argument"))
40+
})
41+
It("Set command without flag hostname", func() {
42+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789")
43+
Expect(err).To(HaveOccurred())
44+
Expect(err.Error()).To(ContainSubstring(`required flag(s) "origin", "path" not set`))
45+
})
46+
It("Set command without flag origin", func() {
47+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123")
48+
Expect(err).To(HaveOccurred())
49+
Expect(err.Error()).To(ContainSubstring(`required flag(s) "path" not set`))
50+
})
51+
It("Set command without flag http or https", func() {
52+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123", "--path", "/example/videos")
53+
Expect(err).To(HaveOccurred())
54+
Expect(err.Error()).To(ContainSubstring(`Incorrect Usage: 'http or https' is required`))
55+
})
56+
It("Set command with flag wrong origin-type", func() {
57+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123", "--path", "/example/videos", "--http", "80", "--origin-type", "asdfgh")
58+
Expect(err).To(HaveOccurred())
59+
Expect(err.Error()).To(ContainSubstring(`Incorrect Usage: --origintype`))
60+
})
61+
It("Set command with flag wrong optimize", func() {
62+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123", "--path", "/example/videos", "--http", "80", "--optimize", "notPermit")
63+
Expect(err).To(HaveOccurred())
64+
Expect(err.Error()).To(ContainSubstring(`Incorrect Usage: --optimize`))
65+
})
66+
It("Set command with flag wrong cache-key", func() {
67+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123", "--path", "/example/videos", "--http", "80", "--cache-key", "notPermit")
68+
Expect(err).To(HaveOccurred())
69+
Expect(err.Error()).To(ContainSubstring(`Incorrect Usage: --cache-key`))
70+
})
71+
It("Set command with flag originType like storage and empty bucket-name", func() {
72+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123", "--path", "/example/videos", "--http", "80", "--origin-type", "storage")
73+
Expect(err).To(HaveOccurred())
74+
Expect(err.Error()).To(ContainSubstring(`Incorrect Usage: --bucket-name can not be empty`))
75+
})
76+
})
77+
78+
Context("Cdn origin add, correct use", func() {
79+
It("return cdn origin add", func() {
80+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123","--path", "/example/videos/", "--http", "80", "--origin-type", "storage", "--bucket-name", "bucketName", "--file-extensions", "jpg")
81+
Expect(err).NotTo(HaveOccurred())
82+
Expect(fakeUI.Outputs()).To(ContainSubstring("CDN Unique ID"))
83+
Expect(fakeUI.Outputs()).To(ContainSubstring("354034879028850"))
84+
Expect(fakeUI.Outputs()).To(ContainSubstring("File Extension"))
85+
Expect(fakeUI.Outputs()).To(ContainSubstring("jpg,pdf,jpeg,png"))
86+
Expect(fakeUI.Outputs()).To(ContainSubstring("Header"))
87+
Expect(fakeUI.Outputs()).To(ContainSubstring("header.test.com"))
88+
Expect(fakeUI.Outputs()).To(ContainSubstring("Path"))
89+
Expect(fakeUI.Outputs()).To(ContainSubstring("/example/videos"))
90+
Expect(fakeUI.Outputs()).To(ContainSubstring("Cache Key Rule"))
91+
Expect(fakeUI.Outputs()).To(ContainSubstring("include-all"))
92+
Expect(fakeUI.Outputs()).To(ContainSubstring("Performance Configuration"))
93+
Expect(fakeUI.Outputs()).To(ContainSubstring("General web delivery"))
94+
Expect(fakeUI.Outputs()).To(ContainSubstring("Status"))
95+
Expect(fakeUI.Outputs()).To(ContainSubstring("RUNNING"))
96+
})
97+
It("return cdn in format json", func() {
98+
err := testhelpers.RunCobraCommand(cliCommand.Command, "123456789", "--origin", "123.123.123.123","--path", "/example/videos/", "--http", "80", "--output", "json")
99+
Expect(err).NotTo(HaveOccurred())
100+
Expect(fakeUI.Outputs()).To(ContainSubstring(`"Name": "CDN Unique ID",`))
101+
Expect(fakeUI.Outputs()).To(ContainSubstring(`"Value": "354034879028850"`))
102+
Expect(fakeUI.Outputs()).To(ContainSubstring(`[`))
103+
Expect(fakeUI.Outputs()).To(ContainSubstring(`{`))
104+
Expect(fakeUI.Outputs()).To(ContainSubstring(`}`))
105+
Expect(fakeUI.Outputs()).To(ContainSubstring(`]`))
106+
})
107+
})
108+
})
109+
})

plugin/commands/cdn/origin_list.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package cdn
2+
3+
import (
4+
"github.com/softlayer/softlayer-go/datatypes"
5+
"github.com/spf13/cobra"
6+
7+
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/terminal"
8+
9+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/errors"
10+
. "github.ibm.com/SoftLayer/softlayer-cli/plugin/i18n"
11+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/managers"
12+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/metadata"
13+
"github.ibm.com/SoftLayer/softlayer-cli/plugin/utils"
14+
)
15+
16+
type OriginListCommand struct {
17+
*metadata.SoftlayerCommand
18+
CdnManager managers.CdnManager
19+
Command *cobra.Command
20+
}
21+
22+
func NewOriginListCommand(sl *metadata.SoftlayerCommand) *OriginListCommand {
23+
thisCmd := &OriginListCommand{
24+
SoftlayerCommand: sl,
25+
CdnManager: managers.NewCdnManager(sl.Session),
26+
}
27+
cobraCmd := &cobra.Command{
28+
Use: "origin-list " + T("IDENTIFIER"),
29+
Short: T("List origin path for an existing CDN mapping."),
30+
Long: T("${COMMAND_NAME} sl cdn origin-list"),
31+
Args: metadata.OneArgs,
32+
RunE: func(cmd *cobra.Command, args []string) error {
33+
return thisCmd.Run(args)
34+
},
35+
}
36+
thisCmd.Command = cobraCmd
37+
return thisCmd
38+
}
39+
40+
func (cmd *OriginListCommand) Run(args []string) error {
41+
cdnId := args[0]
42+
43+
outputFormat := cmd.GetOutputFlag()
44+
45+
cdnOriginList, err := cmd.CdnManager.GetOrigins(cdnId)
46+
if err != nil {
47+
return errors.NewAPIError(T("Failed to get origins list for CDN: {{.cdnId}}.", map[string]interface{}{"cdnId": cdnId}), err.Error(), 2)
48+
}
49+
50+
PrintOriginsList(cdnOriginList, cmd.UI, outputFormat)
51+
return nil
52+
}
53+
54+
func PrintOriginsList(cdnOriginList []datatypes.Container_Network_CdnMarketplace_Configuration_Mapping_Path, ui terminal.UI, outputFormat string) {
55+
table := ui.Table([]string{
56+
T("Path"),
57+
T("Origin"),
58+
T("Http Port"),
59+
T("Https Port"),
60+
T("Status"),
61+
})
62+
for _, origin := range cdnOriginList {
63+
table.Add(
64+
utils.FormatStringPointer(origin.Path),
65+
utils.FormatStringPointer(origin.Origin),
66+
utils.FormatIntPointer(origin.HttpPort),
67+
utils.FormatIntPointer(origin.HttpsPort),
68+
utils.FormatStringPointer(origin.Status),
69+
)
70+
}
71+
utils.PrintTable(ui, table, outputFormat)
72+
}

0 commit comments

Comments
 (0)