11package cluster
22
33import (
4- "fmt"
5-
64 "github.com/spf13/cobra"
75
8- bookingv1 "github.com/qdrant/qdrant-cloud-public-api/gen/go/qdrant/cloud/booking/v1"
9-
10- "github.com/qdrant/qcloud-cli/internal/cmd/output"
11- "github.com/qdrant/qcloud-cli/internal/resource"
6+ "github.com/qdrant/qcloud-cli/internal/cmd/completion"
127 "github.com/qdrant/qcloud-cli/internal/state"
138)
149
15- // packageFilter holds the parameters for filtering packages.
16- // Zero values for CPU/RAM/GPU mean "do not filter on that dimension".
17- type packageFilter struct {
18- CPU resource.Millicores
19- RAM resource.ByteQuantity
20- GPU resource.Millicores
21- IncludeGPU bool
22- MultiAz bool
23- }
24-
25- // filteredPackages fetches active packages matching the given filter.
26- // Returns nil (no completions) if --cloud-provider is not set.
27- func filteredPackages (cmd * cobra.Command , s * state.State , f packageFilter ) ([]* bookingv1.Package , error ) {
10+ // cloudProviderFn reads the cloud provider and region from the command's flags.
11+ func cloudProviderFn (cmd * cobra.Command ) (string , * string ) {
2812 provider , _ := cmd .Flags ().GetString ("cloud-provider" )
29- if provider == "" {
30- return nil , nil
31- }
32-
33- ctx := cmd .Context ()
34- client , err := s .Client (ctx )
35- if err != nil {
36- return nil , err
37- }
38-
39- accountID , err := s .AccountID ()
40- if err != nil {
41- return nil , err
42- }
43-
4413 region , _ := cmd .Flags ().GetString ("cloud-region" )
45- req := & bookingv1.ListPackagesRequest {
46- AccountId : accountID ,
47- CloudProviderId : provider ,
48- Statuses : []bookingv1.PackageStatus {bookingv1 .PackageStatus_PACKAGE_STATUS_ACTIVE },
49- Gpu : & f .IncludeGPU ,
50- }
5114 if region != "" {
52- req .CloudProviderRegionId = & region
53- }
54- if f .MultiAz {
55- req .MultiAz = new (true )
56- }
57-
58- resp , err := client .Booking ().ListPackages (ctx , req )
59- if err != nil {
60- return nil , err
61- }
62-
63- var result []* bookingv1.Package
64- for _ , p := range resp .GetItems () {
65- rc := p .GetResourceConfiguration ()
66- if f .CPU != 0 {
67- pkgCPU , _ := resource .ParseMillicores (rc .GetCpu ())
68- if pkgCPU != f .CPU {
69- continue
70- }
71- }
72- if f .RAM != 0 {
73- pkgRAM , _ := resource .ParseByteQuantity (rc .GetRam ())
74- if pkgRAM != f .RAM {
75- continue
76- }
77- }
78- if f .GPU != 0 {
79- pkgGPU , _ := resource .ParseMillicores (rc .GetGpu ())
80- if pkgGPU != f .GPU {
81- continue
82- }
83- }
84- result = append (result , p )
15+ return provider , & region
8516 }
86- return result , nil
17+ return provider , nil
8718}
8819
89- // cpuCompletion returns a completion function for the --cpu flag.
9020func cpuCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
91- return func (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
92- provider , _ := cmd .Flags ().GetString ("cloud-provider" )
93- if provider == "" {
94- return nil , cobra .ShellCompDirectiveNoFileComp
95- }
96- ram := * cmd .Flags ().Lookup ("ram" ).Value .(* resource.ByteQuantity )
97- gpu := * cmd .Flags ().Lookup ("gpu" ).Value .(* resource.Millicores )
98- multiAz , _ := cmd .Flags ().GetBool ("multi-az" )
99- pkgs , err := filteredPackages (cmd , s , packageFilter {
100- RAM : ram ,
101- GPU : gpu ,
102- IncludeGPU : gpu != 0 ,
103- MultiAz : multiAz ,
104- })
105- if err != nil {
106- return nil , cobra .ShellCompDirectiveError
107- }
108-
109- seen := make (map [resource.Millicores ]struct {})
110- var completions []string
111- for _ , p := range pkgs {
112- v , err := resource .ParseMillicores (p .GetResourceConfiguration ().GetCpu ())
113- if err != nil {
114- cobra .CompErrorln (fmt .Sprintf ("package %s: %v" , p .GetName (), err ))
115- continue
116- }
117- if _ , ok := seen [v ]; ! ok {
118- seen [v ] = struct {}{}
119- completions = append (completions , v .String ())
120- }
121- }
122- return completions , cobra .ShellCompDirectiveNoFileComp
123- }
21+ return completion .CPUCompletion (s , cloudProviderFn )
12422}
12523
126- // ramCompletion returns a completion function for the --ram flag.
12724func ramCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
128- return func (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
129- provider , _ := cmd .Flags ().GetString ("cloud-provider" )
130- if provider == "" {
131- return nil , cobra .ShellCompDirectiveNoFileComp
132- }
133- cpu := * cmd .Flags ().Lookup ("cpu" ).Value .(* resource.Millicores )
134- gpu := * cmd .Flags ().Lookup ("gpu" ).Value .(* resource.Millicores )
135- multiAz , _ := cmd .Flags ().GetBool ("multi-az" )
136- pkgs , err := filteredPackages (cmd , s , packageFilter {
137- CPU : cpu ,
138- GPU : gpu ,
139- IncludeGPU : gpu != 0 ,
140- MultiAz : multiAz ,
141- })
142- if err != nil {
143- return nil , cobra .ShellCompDirectiveError
144- }
145-
146- seen := make (map [resource.ByteQuantity ]struct {})
147- var completions []string
148- for _ , p := range pkgs {
149- v , err := resource .ParseByteQuantity (p .GetResourceConfiguration ().GetRam ())
150- if err != nil {
151- cobra .CompErrorln (fmt .Sprintf ("package %s: %v" , p .GetName (), err ))
152- continue
153- }
154- if _ , ok := seen [v ]; ! ok {
155- seen [v ] = struct {}{}
156- completions = append (completions , resource .FormatByteQuantity (v , resource .UnitGiB ))
157- }
158- }
159- return completions , cobra .ShellCompDirectiveNoFileComp
160- }
25+ return completion .RAMCompletion (s , cloudProviderFn )
16126}
16227
163- // diskCompletion returns a completion function for the --disk flag.
16428func diskCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
165- return func (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
166- provider , _ := cmd .Flags ().GetString ("cloud-provider" )
167- if provider == "" {
168- return nil , cobra .ShellCompDirectiveNoFileComp
169- }
170- cpu := * cmd .Flags ().Lookup ("cpu" ).Value .(* resource.Millicores )
171- ram := * cmd .Flags ().Lookup ("ram" ).Value .(* resource.ByteQuantity )
172- gpu := * cmd .Flags ().Lookup ("gpu" ).Value .(* resource.Millicores )
173- multiAz , _ := cmd .Flags ().GetBool ("multi-az" )
174- pkgs , err := filteredPackages (cmd , s , packageFilter {
175- CPU : cpu ,
176- RAM : ram ,
177- GPU : gpu ,
178- IncludeGPU : gpu != 0 ,
179- MultiAz : multiAz ,
180- })
181- if err != nil {
182- return nil , cobra .ShellCompDirectiveError
183- }
184-
185- seen := make (map [resource.ByteQuantity ]struct {})
186- var completions []string
187- for _ , p := range pkgs {
188- v , err := resource .ParseByteQuantity (p .GetResourceConfiguration ().GetDisk ())
189- if err != nil {
190- cobra .CompErrorln (fmt .Sprintf ("package %s: %v" , p .GetName (), err ))
191- continue
192- }
193- if _ , ok := seen [v ]; ! ok {
194- seen [v ] = struct {}{}
195- completions = append (completions , v .String ())
196- }
197- }
198- return completions , cobra .ShellCompDirectiveNoFileComp
199- }
29+ return completion .DiskCompletion (s , cloudProviderFn )
20030}
20131
202- // gpuCompletion returns a completion function for the --gpu flag.
20332func gpuCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
204- return func (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
205- provider , _ := cmd .Flags ().GetString ("cloud-provider" )
206- if provider == "" {
207- return nil , cobra .ShellCompDirectiveNoFileComp
208- }
209- cpu := * cmd .Flags ().Lookup ("cpu" ).Value .(* resource.Millicores )
210- ram := * cmd .Flags ().Lookup ("ram" ).Value .(* resource.ByteQuantity )
211- multiAz , _ := cmd .Flags ().GetBool ("multi-az" )
212- pkgs , err := filteredPackages (cmd , s , packageFilter {
213- CPU : cpu ,
214- RAM : ram ,
215- IncludeGPU : true ,
216- MultiAz : multiAz ,
217- })
218- if err != nil {
219- return nil , cobra .ShellCompDirectiveError
220- }
33+ return completion .GPUCompletion (s , cloudProviderFn )
34+ }
22135
222- seen := make (map [resource.Millicores ]struct {})
223- var completions []string
224- for _ , p := range pkgs {
225- m , err := resource .ParseMillicores (p .GetResourceConfiguration ().GetGpu ())
226- if err != nil || m <= 0 || int64 (m )% 1000 != 0 {
227- continue
228- }
229- if _ , ok := seen [m ]; ! ok {
230- seen [m ] = struct {}{}
231- completions = append (completions , m .String ())
232- }
233- }
234- return completions , cobra .ShellCompDirectiveNoFileComp
235- }
36+ func packageCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
37+ return completion .PackageNameCompletion (s , cloudProviderFn )
23638}
23739
23840// diskPerformanceCompletion returns a static completion function for the --disk-performance flag.
@@ -255,50 +57,3 @@ func rebalanceStrategyCompletion() func(*cobra.Command, []string, string) ([]str
25557 return []string {rebalanceByCount , rebalanceBySize , rebalanceByCountAndSize }, cobra .ShellCompDirectiveNoFileComp
25658 }
25759}
258-
259- // packageCompletion returns a completion function for the --package flag.
260- func packageCompletion (s * state.State ) func (* cobra.Command , []string , string ) ([]string , cobra.ShellCompDirective ) {
261- return func (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
262- provider , _ := cmd .Flags ().GetString ("cloud-provider" )
263- if provider == "" {
264- return nil , cobra .ShellCompDirectiveNoFileComp
265- }
266-
267- ctx := cmd .Context ()
268- client , err := s .Client (ctx )
269- if err != nil {
270- return nil , cobra .ShellCompDirectiveError
271- }
272-
273- accountID , err := s .AccountID ()
274- if err != nil {
275- return nil , cobra .ShellCompDirectiveError
276- }
277-
278- region , _ := cmd .Flags ().GetString ("cloud-region" )
279- req := & bookingv1.ListPackagesRequest {
280- AccountId : accountID ,
281- CloudProviderId : provider ,
282- Statuses : []bookingv1.PackageStatus {bookingv1 .PackageStatus_PACKAGE_STATUS_ACTIVE },
283- }
284- if region != "" {
285- req .CloudProviderRegionId = & region
286- }
287-
288- resp , err := client .Booking ().ListPackages (ctx , req )
289- if err != nil {
290- return nil , cobra .ShellCompDirectiveError
291- }
292-
293- completions := make ([]string , 0 , len (resp .GetItems ()))
294- for _ , p := range resp .GetItems () {
295- desc := output .PackageTier (p .GetTier ())
296- if rc := p .GetResourceConfiguration (); rc != nil {
297- desc += fmt .Sprintf (" | %s RAM / %s CPU / %s disk" , rc .GetRam (), rc .GetCpu (), rc .GetDisk ())
298- }
299- desc += " | " + formatMillicents (p .GetUnitIntPricePerHour (), p .GetCurrency ()) + "/hr"
300- completions = append (completions , p .GetName ()+ "\t " + desc )
301- }
302- return completions , cobra .ShellCompDirectiveNoFileComp
303- }
304- }
0 commit comments