Skip to content

Commit 5658e4c

Browse files
authored
Merge pull request #38 from liquidweb/template-commands
Template commands
2 parents bb65079 + 02aff92 commit 5658e4c

File tree

7 files changed

+308
-3
lines changed

7 files changed

+308
-3
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,13 @@ The Cloud features you can use in manage.liquidweb.com on your Cloud Servers you
6464
## Plans
6565

6666
A plan is a pre-defined yaml with optional template variables that can be used to
67-
repeate specific tasks.
67+
repeate specific tasks. Fields in the yaml file match the params you would send
68+
to the command.
6869

69-
Currently only "lw cloud server create" is implemented.
70+
Current commands supported in a `plan` file:
71+
72+
- cloud server create
73+
- cloud template restore
7074

7175
Example:
7276

cmd/cloudTemplate.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Copyright © LiquidWeb
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"os"
20+
21+
"github.com/spf13/cobra"
22+
)
23+
24+
var cloudTemplateCmd = &cobra.Command{
25+
Use: "template",
26+
Short: "Cloud template specific operations",
27+
Long: `Cloud template specific operations.
28+
29+
For a full list of capabilities, please refer to the "Available Commands" section.`,
30+
Run: func(cmd *cobra.Command, args []string) {
31+
cmd.Help()
32+
os.Exit(1)
33+
},
34+
}
35+
36+
func init() {
37+
cloudCmd.AddCommand(cloudTemplateCmd)
38+
}

cmd/cloudTemplateList.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
Copyright © LiquidWeb
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"fmt"
20+
"strings"
21+
22+
"github.com/spf13/cast"
23+
"github.com/spf13/cobra"
24+
25+
"github.com/liquidweb/liquidweb-cli/instance"
26+
)
27+
28+
var cloudTemplateListCmd = &cobra.Command{
29+
Use: "list",
30+
Short: "Displays a list of cloud VPS templates",
31+
Long: `Displays a list of cloud VPS templates.`,
32+
Run: func(cmd *cobra.Command, args []string) {
33+
zoneFlag, _ := cmd.Flags().GetInt("zone")
34+
filterOsFlag, _ := cmd.Flags().GetString("os")
35+
filterManageLevelFlag, _ := cmd.Flags().GetString("manage-level")
36+
37+
templateList, err := lwCliInst.AllPaginatedResults(&instance.AllPaginatedResultsArgs{
38+
Method: "bleed/storm/template/list",
39+
ResultsPerPage: 100,
40+
})
41+
if err != nil {
42+
lwCliInst.Die(err)
43+
}
44+
45+
zonesResults, err := lwCliInst.LwCliApiClient.Call("bleed/network/zone/list", nil)
46+
if err != nil {
47+
lwCliInst.Die(err)
48+
}
49+
50+
type ZoneInfo struct {
51+
Id int
52+
Name string
53+
RegionName string
54+
}
55+
zones := make(map[int]*ZoneInfo)
56+
zoneMap := zonesResults.(map[string]interface{})
57+
58+
for _, item := range zoneMap["items"].([]interface{}) {
59+
z := item.(map[string]interface{})
60+
61+
zone := &ZoneInfo{
62+
Id: cast.ToInt(z["id"]),
63+
Name: cast.ToString(z["name"]),
64+
RegionName: cast.ToString(z["region"].(map[string]interface{})["name"]),
65+
}
66+
zones[zone.Id] = zone
67+
}
68+
69+
for _, template := range templateList.Items {
70+
if cast.ToBool(template["deprecated"]) {
71+
continue
72+
}
73+
74+
if !strings.HasPrefix(strings.ToLower(cast.ToString(template["os"])), strings.ToLower(filterOsFlag)) {
75+
continue
76+
}
77+
78+
if filterManageLevelFlag != "" {
79+
if strings.ToLower(filterManageLevelFlag) != strings.ToLower(cast.ToString(template["manage_level"])) {
80+
continue
81+
}
82+
}
83+
84+
if zoneFlag != -1 {
85+
var skip bool = true
86+
87+
for templateZoneStr, _ := range template["zone_availability"].(map[string]interface{}) {
88+
templateZone := cast.ToInt(templateZoneStr)
89+
if templateZone == zoneFlag {
90+
skip = false
91+
}
92+
}
93+
94+
if skip {
95+
continue
96+
}
97+
}
98+
99+
fmt.Println("name:", template["name"])
100+
fmt.Println(" description: ", template["description"])
101+
fmt.Print(" os: ", template["os"])
102+
fmt.Println(", manage-level:", template["manage_level"])
103+
fmt.Println(" Zone Availibility:")
104+
105+
for templateZoneStr, _ := range template["zone_availability"].(map[string]interface{}) {
106+
templateZone := cast.ToInt(templateZoneStr)
107+
if z, ok := zones[templateZone]; ok {
108+
fmt.Printf(" %5d - %s - %s\n", z.Id, z.Name, z.RegionName)
109+
}
110+
111+
}
112+
113+
fmt.Println("")
114+
}
115+
},
116+
}
117+
118+
func init() {
119+
cloudTemplateCmd.AddCommand(cloudTemplateListCmd)
120+
cloudTemplateListCmd.Flags().Int("zone", -1, "id of zone to filter by")
121+
cloudTemplateListCmd.Flags().String("os", "", "filter if os begins with string (i.e. linux, win)")
122+
cloudTemplateListCmd.Flags().String("manage-level", "", "filter list by management level")
123+
}

cmd/cloudTemplateRestore.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
Copyright © LiquidWeb
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package cmd
17+
18+
import (
19+
"fmt"
20+
21+
"github.com/spf13/cobra"
22+
23+
"github.com/liquidweb/liquidweb-cli/instance"
24+
)
25+
26+
var cloudTemplateRestoreCmd = &cobra.Command{
27+
Use: "restore",
28+
Short: "Restore a Cloud Template on a Cloud Server",
29+
Long: `Restore a Cloud Template on a Cloud Server.`,
30+
Run: func(cmd *cobra.Command, args []string) {
31+
params := &instance.CloudTemplateRestoreParams{}
32+
33+
params.UniqId, _ = cmd.Flags().GetString("uniq-id")
34+
params.Template, _ = cmd.Flags().GetString("template")
35+
36+
result, err := lwCliInst.CloudTemplateRestore(params)
37+
if err != nil {
38+
lwCliInst.Die(err)
39+
}
40+
41+
fmt.Printf("Restoring template! %s\n", result)
42+
fmt.Printf("\tcheck progress with 'cloud server status --uniq-id %s'\n", params.UniqId)
43+
},
44+
}
45+
46+
func init() {
47+
cloudTemplateCmd.AddCommand(cloudTemplateRestoreCmd)
48+
49+
cloudTemplateRestoreCmd.Flags().String("uniq-id", "", "uniq-id of Cloud Server")
50+
cloudTemplateRestoreCmd.Flags().String("template", "", "name of template to restore")
51+
52+
cloudTemplateRestoreCmd.MarkFlagRequired("uniq-id")
53+
cloudTemplateRestoreCmd.MarkFlagRequired("template")
54+
}

instance/cloudTemplateRestore.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright © LiquidWeb
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package instance
17+
18+
import (
19+
"github.com/liquidweb/liquidweb-cli/types/api"
20+
"github.com/liquidweb/liquidweb-cli/validate"
21+
)
22+
23+
type CloudTemplateRestoreParams struct {
24+
Template string `yaml:"template"`
25+
UniqId string `yaml:"uniq-id"`
26+
}
27+
28+
func (ci *Client) CloudTemplateRestore(params *CloudTemplateRestoreParams) (string, error) {
29+
validateFields := map[interface{}]interface{}{
30+
params.UniqId: "UniqId",
31+
}
32+
if err := validate.Validate(validateFields); err != nil {
33+
return "", err
34+
}
35+
36+
apiArgs := map[string]interface{}{"template": params.Template, "uniq_id": params.UniqId}
37+
38+
var details apiTypes.CloudTemplateRestoreResponse
39+
err := ci.CallLwApiInto("bleed/storm/template/restore", apiArgs, &details)
40+
if err != nil {
41+
return "", err
42+
}
43+
44+
return details.Reimaged, nil
45+
}

instance/plan.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ type Plan struct {
2525
}
2626

2727
type PlanCloud struct {
28-
Server *PlanCloudServer
28+
Server *PlanCloudServer
29+
Template *PlanCloudTemplate
2930
}
3031

3132
type PlanCloudServer struct {
3233
Create []CloudServerCreateParams
3334
}
3435

36+
type PlanCloudTemplate struct {
37+
Restore []CloudTemplateRestoreParams
38+
}
39+
3540
func (ci *Client) ProcessPlan(plan *Plan) error {
3641

3742
if plan.Cloud != nil {
@@ -51,6 +56,12 @@ func (ci *Client) processPlanCloud(cloud *PlanCloud) error {
5156
}
5257
}
5358

59+
if cloud.Template != nil {
60+
if err := ci.processPlanCloudTemplate(cloud.Template); err != nil {
61+
return err
62+
}
63+
}
64+
5465
return nil
5566
}
5667

@@ -80,3 +91,29 @@ func (ci *Client) processPlanCloudServerCreate(params *CloudServerCreateParams)
8091
uniqId, uniqId)
8192
return nil
8293
}
94+
95+
func (ci *Client) processPlanCloudTemplate(template *PlanCloudTemplate) error {
96+
97+
if template.Restore != nil {
98+
for _, c := range template.Restore {
99+
if err := ci.processPlanCloudTemplateRestore(&c); err != nil {
100+
return err
101+
}
102+
}
103+
}
104+
105+
return nil
106+
}
107+
108+
func (ci *Client) processPlanCloudTemplateRestore(params *CloudTemplateRestoreParams) error {
109+
110+
result, err := ci.CloudTemplateRestore(params)
111+
if err != nil {
112+
ci.Die(err)
113+
}
114+
115+
fmt.Printf("Restoring template! %s\n", result)
116+
fmt.Printf("\tcheck progress with 'cloud server status --uniq-id %s'\n", params.UniqId)
117+
118+
return nil
119+
}

types/api/cloud.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ type CloudImageDeleteResponse struct {
255255
Deleted int64 `json:"deleted" mapstructure:"deleted"`
256256
}
257257

258+
type CloudTemplateRestoreResponse struct {
259+
Reimaged string `json:"reimaged" mapstructure:"reimaged"`
260+
}
261+
258262
type CloudServerIsBlockStorageOptimized struct {
259263
IsOptimized bool `json:"is_optimized" mapstructure:"is_optimized"`
260264
}

0 commit comments

Comments
 (0)