Skip to content

Commit 4659734

Browse files
author
lijianguo
committed
feat(controller):add drycc resource cmd
1 parent 08e24d4 commit 4659734

8 files changed

Lines changed: 891 additions & 1 deletion

File tree

cmd/cmd.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ type Commander interface {
104104
VolumesList(string, int) error
105105
VolumesMount(string, string, []string) error
106106
VolumesUnmount(string, string, []string) error
107+
ResourcesCreate(string, string, string, []string) error
108+
ResourcesList(string, int) error
109+
ResourceDelete(string, string) error
110+
ResourceGet(string, string) error
111+
ResourcePut(string, string, string, []string) error
112+
ResourceBind(string, string) error
113+
ResourceUnbind(string, string) error
107114
}
108115

109116
// DryccCmd is an implementation of Commander.

cmd/resources.go

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"github.com/drycc/controller-sdk-go/api"
6+
"github.com/drycc/controller-sdk-go/resources"
7+
"github.com/drycc/pkg/prettyprint"
8+
"io"
9+
"regexp"
10+
"strings"
11+
)
12+
13+
// ResourcesCreate create a resource for the application
14+
func (d *DryccCmd) ResourcesCreate(appID, plan string, name string, params []string) error {
15+
s, appID, err := load(d.ConfigFile, appID)
16+
17+
if err != nil {
18+
return err
19+
}
20+
21+
d.Printf("Creating %s to %s... ", name, appID)
22+
23+
paramsMap, err := parseParams(params)
24+
if err != nil {
25+
return err
26+
}
27+
28+
quit := progress(d.WOut)
29+
resource := api.Resource{
30+
Name: name,
31+
Plan: plan,
32+
Options: paramsMap,
33+
}
34+
_, err = resources.Create(s.Client, appID, resource)
35+
quit <- true
36+
<-quit
37+
if d.checkAPICompatibility(s.Client, err) != nil {
38+
return err
39+
}
40+
41+
d.Println("done")
42+
return nil
43+
}
44+
45+
// ResourcesList list resources in the application
46+
func (d *DryccCmd) ResourcesList(appID string, results int) error {
47+
s, appID, err := load(d.ConfigFile, appID)
48+
49+
if err != nil {
50+
return err
51+
}
52+
53+
if results == defaultLimit {
54+
results = s.Limit
55+
}
56+
resources, count, err := resources.List(s.Client, appID, results)
57+
if d.checkAPICompatibility(s.Client, err) != nil {
58+
return err
59+
}
60+
61+
if count == 0 {
62+
d.Println("Could not find any resources")
63+
} else {
64+
printResources(d, appID, resources, d.WOut)
65+
}
66+
return nil
67+
}
68+
69+
// ResourceGet describe a resource from the application
70+
func (d *DryccCmd) ResourceGet(appID, name string) error {
71+
s, appID, err := load(d.ConfigFile, appID)
72+
73+
if err != nil {
74+
return err
75+
}
76+
77+
//d.Printf(" %s from %s... ", name, appID)
78+
79+
resource, err := resources.Get(s.Client, appID, name)
80+
if d.checkAPICompatibility(s.Client, err) != nil {
81+
return err
82+
}
83+
// todo format data json to yaml
84+
printResourceDetail(d, appID, resource, d.WOut)
85+
//d.Println(resource)
86+
return nil
87+
}
88+
89+
// ResourceDelete delete a resource from the application
90+
func (d *DryccCmd) ResourceDelete(appID, name string) error {
91+
s, appID, err := load(d.ConfigFile, appID)
92+
93+
if err != nil {
94+
return err
95+
}
96+
97+
d.Printf("Deleting %s from %s... ", name, appID)
98+
99+
quit := progress(d.WOut)
100+
err = resources.Delete(s.Client, appID, name)
101+
quit <- true
102+
<-quit
103+
if d.checkAPICompatibility(s.Client, err) != nil {
104+
return err
105+
}
106+
107+
d.Println("done")
108+
return nil
109+
}
110+
111+
// ResourcePut update a resource for the application
112+
func (d *DryccCmd) ResourcePut(appID, plan string, name string, params []string) error {
113+
s, appID, err := load(d.ConfigFile, appID)
114+
115+
if err != nil {
116+
return err
117+
}
118+
119+
d.Printf("Updating %s to %s... ", name, appID)
120+
121+
paramsMap, err := parseParams(params)
122+
if err != nil {
123+
return err
124+
}
125+
126+
quit := progress(d.WOut)
127+
resource := api.Resource{
128+
Plan: plan,
129+
Options: paramsMap,
130+
}
131+
_, err = resources.Put(s.Client, appID, name, resource)
132+
quit <- true
133+
<-quit
134+
if d.checkAPICompatibility(s.Client, err) != nil {
135+
return err
136+
}
137+
138+
d.Println("done")
139+
return nil
140+
}
141+
142+
// ResourceBind mount a resource to process of the application
143+
func (d *DryccCmd) ResourceBind(appID string, name string) error {
144+
s, appID, err := load(d.ConfigFile, appID)
145+
146+
if err != nil {
147+
return err
148+
}
149+
150+
d.Print("Binding resource... ")
151+
152+
quit := progress(d.WOut)
153+
bindAction := api.Binding{BindAction: "bind"}
154+
_, err = resources.Binding(s.Client, appID, name, bindAction)
155+
quit <- true
156+
<-quit
157+
if d.checkAPICompatibility(s.Client, err) != nil {
158+
return err
159+
}
160+
161+
d.Print("done\n")
162+
163+
return nil
164+
}
165+
166+
// ResourceUnbind resource a resource the application
167+
func (d *DryccCmd) ResourceUnbind(appID string, name string) error {
168+
s, appID, err := load(d.ConfigFile, appID)
169+
170+
if err != nil {
171+
return err
172+
}
173+
174+
d.Print("Unbinding resource... ")
175+
176+
quit := progress(d.WOut)
177+
bindAction := api.Binding{BindAction: "unbind"}
178+
_, err = resources.Binding(s.Client, appID, name, bindAction)
179+
quit <- true
180+
<-quit
181+
if d.checkAPICompatibility(s.Client, err) != nil {
182+
return err
183+
}
184+
185+
d.Print("done\n")
186+
187+
return nil
188+
}
189+
190+
// printResources format Resources data
191+
func printResources(d *DryccCmd, appID string, resources api.Resources, wOut io.Writer) {
192+
193+
fmt.Fprintf(wOut, "=== %s resources\n", appID)
194+
195+
for _, resource := range resources {
196+
fmt.Fprintf(wOut, "%s\t%s\n", resource.Name, resource.Plan)
197+
}
198+
}
199+
200+
func printResourceDetail(d *DryccCmd, appID string, resource api.Resource, wOut io.Writer) {
201+
d.Printf("=== %s resource %s\n", appID, resource.Name)
202+
203+
dataMap := make(map[string]string)
204+
for key, value := range resource.Data {
205+
dataMap[key+":"] = fmt.Sprintf("%v", value)
206+
}
207+
optionsMap := make(map[string]string)
208+
for key, value := range resource.Options {
209+
optionsMap[key+":"] = fmt.Sprintf("%v", value)
210+
}
211+
lenDataMap := maxLen(dataMap)
212+
lenOptionsMap := maxLen(optionsMap)
213+
tempArray := []int{lenDataMap, lenOptionsMap, len("binding:")}
214+
max := maxNum(tempArray...) + 5
215+
d.Print(fmt.Sprintf("plan:%s%s\n", strings.Repeat(" ", max-len("plan:")), resource.Plan))
216+
d.Print(fmt.Sprintf("status:%s%s\n", strings.Repeat(" ", max-len("status:")), resource.Status))
217+
d.Print(fmt.Sprintf("binding:%s%s\n", strings.Repeat(" ", max-len("binding:")), resource.Binding))
218+
219+
if lenDataMap != 0 {
220+
d.Println()
221+
d.Print(prettyprint.PrettyTabs(dataMap, max-lenDataMap))
222+
}
223+
if lenOptionsMap != 0 {
224+
d.Println()
225+
d.Print(prettyprint.PrettyTabs(optionsMap, max-lenOptionsMap))
226+
}
227+
}
228+
229+
func maxLen(msg map[string]string) int {
230+
// find the longest key so we know how much padding to use
231+
max := 0
232+
for key := range msg {
233+
if len(key) > max {
234+
max = len(key)
235+
}
236+
}
237+
return max
238+
}
239+
240+
func maxNum(tempArray ...int) int {
241+
// find the longest num so we know how much padding to use
242+
max := 0
243+
for _, temp := range tempArray {
244+
if max < temp {
245+
max = temp
246+
}
247+
}
248+
return max
249+
}
250+
251+
// parseParams transfer params to map
252+
func parseParams(params []string) (map[string]interface{}, error) {
253+
paramsMap := make(map[string]interface{})
254+
255+
regex := regexp.MustCompile(`^([A-z_]+[A-z0-9_]*)=([\s\S]*)$`)
256+
for _, param := range params {
257+
if regex.MatchString(param) {
258+
captures := regex.FindStringSubmatch(param)
259+
paramsMap[captures[1]] = captures[2]
260+
} else {
261+
return nil, fmt.Errorf("'%s' does not match the pattern 'key=var', ex: MODE=test", param)
262+
}
263+
}
264+
265+
return paramsMap, nil
266+
}

0 commit comments

Comments
 (0)