Skip to content

Commit 89a36f9

Browse files
authored
Merge pull request #108 from yjinjo/master
Reallocate functions and modify alias command
2 parents c10160a + f4e5329 commit 89a36f9

File tree

10 files changed

+602
-480
lines changed

10 files changed

+602
-480
lines changed

cmd/commands/api_resources.go renamed to cmd/common/api_resources.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package commands
1+
package common
22

33
import (
44
"context"
@@ -12,7 +12,6 @@ import (
1212

1313
"github.com/cloudforet-io/cfctl/pkg/configs"
1414
"github.com/cloudforet-io/cfctl/pkg/format"
15-
"github.com/cloudforet-io/cfctl/pkg/transport"
1615
"github.com/jhump/protoreflect/grpcreflect"
1716
"github.com/spf13/cobra"
1817
"github.com/spf13/viper"
@@ -41,7 +40,7 @@ func ListAPIResources(serviceName string) error {
4140
}
4241

4342
//endpoint, err := getServiceEndpoint(setting, serviceName)
44-
endpoint, err := transport.GetServiceEndpoint(setting, serviceName)
43+
endpoint, err := configs.GetServiceEndpoint(setting, serviceName)
4544
if err != nil {
4645
return fmt.Errorf("failed to get endpoint for service %s: %v", serviceName, err)
4746
}
@@ -51,7 +50,7 @@ func ListAPIResources(serviceName string) error {
5150
return fmt.Errorf("failed to load short names: %v", err)
5251
}
5352

54-
data, err := fetchServiceResources(serviceName, endpoint, shortNamesMap, setting)
53+
data, err := FetchServiceResources(serviceName, endpoint, shortNamesMap, setting)
5554
if err != nil {
5655
return fmt.Errorf("failed to fetch resources for service %s: %v", serviceName, err)
5756
}
@@ -87,7 +86,7 @@ func loadShortNames() (map[string]string, error) {
8786
return shortNamesMap, nil
8887
}
8988

90-
func fetchServiceResources(serviceName, endpoint string, shortNamesMap map[string]string, config *configs.Setting) ([][]string, error) {
89+
func FetchServiceResources(serviceName, endpoint string, shortNamesMap map[string]string, config *configs.Setting) ([][]string, error) {
9190
parts := strings.Split(endpoint, "://")
9291
if len(parts) != 2 {
9392
return nil, fmt.Errorf("invalid endpoint format: %s", endpoint)

cmd/other/alias.go

+34-233
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
package other
22

33
import (
4-
"fmt"
5-
"os"
6-
"path/filepath"
74
"strings"
85

9-
"github.com/cloudforet-io/cfctl/pkg/transport"
6+
"github.com/cloudforet-io/cfctl/pkg/configs"
7+
"github.com/cloudforet-io/cfctl/pkg/format"
108
"github.com/pterm/pterm"
119
"github.com/spf13/cobra"
12-
"github.com/spf13/viper"
13-
"gopkg.in/yaml.v3"
1410
)
1511

16-
var service string
17-
1812
// AliasCmd represents the alias command
1913
var AliasCmd = &cobra.Command{
2014
Use: "alias",
@@ -25,65 +19,62 @@ var AliasCmd = &cobra.Command{
2519
var addAliasCmd = &cobra.Command{
2620
Use: "add",
2721
Short: "Add a new alias",
28-
Example: ` $ cfctl alias add -k user -v "identity list User"
22+
Example: ` $ cfctl alias add -s identity -k user -v "list User"
2923
3024
Then use it as:
31-
$ cfctl user # This command is same as $ cfctl identity list User`,
25+
$ cfctl identity user # This command is same as $ cfctl identity list User`,
3226
Run: func(cmd *cobra.Command, args []string) {
27+
service, _ := cmd.Flags().GetString("service")
3328
key, _ := cmd.Flags().GetString("key")
3429
value, _ := cmd.Flags().GetString("value")
3530

3631
// Parse command to validate
3732
parts := strings.Fields(value)
38-
if len(parts) < 3 {
39-
pterm.Error.Printf("Invalid command format. Expected '<service> <verb> <resource>', got '%s'\n", value)
33+
if len(parts) < 2 {
34+
pterm.Error.Printf("Invalid command format. Expected '<verb> <resource>', got '%s'\n", value)
4035
return
4136
}
4237

43-
service := parts[0]
44-
verb := parts[1]
45-
resource := parts[2]
38+
verb := parts[0]
39+
resource := parts[1]
4640

47-
if err := validateServiceCommand(service, verb, resource); err != nil {
41+
if err := format.ValidateServiceCommand(service, verb, resource); err != nil {
4842
pterm.Error.Printf("Invalid command: %v\n", err)
4943
return
5044
}
5145

52-
if err := addAlias(key, value); err != nil {
46+
if err := configs.AddAlias(service, key, value); err != nil {
5347
pterm.Error.Printf("Failed to add alias: %v\n", err)
5448
return
5549
}
5650

57-
pterm.Success.Printf("Successfully added alias '%s' for command '%s'\n", key, value)
51+
pterm.Success.Printf("Successfully added alias '%s' for command '%s' in service '%s'\n", key, value, service)
5852
},
5953
}
6054

6155
var removeAliasCmd = &cobra.Command{
62-
Use: "remove",
63-
Short: "Remove an alias",
64-
Example: ` $ cfctl alias remove -k user`,
56+
Use: "remove",
57+
Short: "Remove an alias",
58+
Example: ` # Remove an alias from a specific service
59+
$ cfctl alias remove -s identity -k user`,
6560
Run: func(cmd *cobra.Command, args []string) {
61+
service, _ := cmd.Flags().GetString("service")
6662
key, _ := cmd.Flags().GetString("key")
67-
if key == "" {
68-
pterm.Error.Println("The --key (-k) flag is required")
69-
cmd.Help()
70-
return
71-
}
7263

73-
if err := removeAlias(key); err != nil {
64+
if err := configs.RemoveAlias(service, key); err != nil {
7465
pterm.Error.Printf("Failed to remove alias: %v\n", err)
7566
return
7667
}
7768

78-
pterm.Success.Printf("Successfully removed alias '%s'\n", key)
69+
pterm.Success.Printf("Successfully removed alias '%s' from service '%s'\n", key, service)
7970
},
8071
}
8172

8273
var listAliasCmd = &cobra.Command{
8374
Use: "list",
8475
Short: "List all aliases",
8576
Run: func(cmd *cobra.Command, args []string) {
86-
aliases, err := ListAliases()
77+
aliases, err := configs.ListAliases()
8778
if err != nil {
8879
pterm.Error.Printf("Failed to list aliases: %v\n", err)
8980
return
@@ -96,229 +87,39 @@ var listAliasCmd = &cobra.Command{
9687

9788
// Create table
9889
table := pterm.TableData{
99-
{"Alias", "Command"},
90+
{"Service", "Alias", "Command"},
10091
}
10192

10293
// Add aliases to table
103-
for alias, command := range aliases {
104-
table = append(table, []string{alias, command})
94+
for service, serviceAliases := range aliases {
95+
if serviceMap, ok := serviceAliases.(map[string]interface{}); ok {
96+
for alias, command := range serviceMap {
97+
if cmdStr, ok := command.(string); ok {
98+
table = append(table, []string{service, alias, cmdStr})
99+
}
100+
}
101+
}
105102
}
106103

107104
// Print table
108105
pterm.DefaultTable.WithHasHeader().WithData(table).Render()
109106
},
110107
}
111108

112-
// validateServiceCommand checks if the given verb and resource are valid for the service
113-
func validateServiceCommand(service, verb, resource string) error {
114-
// Get current environment from main setting file
115-
home, err := os.UserHomeDir()
116-
if err != nil {
117-
return fmt.Errorf("failed to get home directory: %v", err)
118-
}
119-
120-
mainV := viper.New()
121-
mainV.SetConfigFile(filepath.Join(home, ".cfctl", "setting.yaml"))
122-
mainV.SetConfigType("yaml")
123-
if err := mainV.ReadInConfig(); err != nil {
124-
return fmt.Errorf("failed to read config: %v", err)
125-
}
126-
127-
currentEnv := mainV.GetString("environment")
128-
if currentEnv == "" {
129-
return fmt.Errorf("no environment set")
130-
}
131-
132-
// Get environment config
133-
envConfig := mainV.Sub(fmt.Sprintf("environments.%s", currentEnv))
134-
if envConfig == nil {
135-
return fmt.Errorf("environment %s not found", currentEnv)
136-
}
137-
138-
endpoint := envConfig.GetString("endpoint")
139-
if endpoint == "" {
140-
return fmt.Errorf("no endpoint found in configuration")
141-
}
142-
143-
endpoint, _ = transport.GetAPIEndpoint(endpoint)
144-
145-
// Fetch endpoints map
146-
endpointsMap, err := transport.FetchEndpointsMap(endpoint)
147-
if err != nil {
148-
return fmt.Errorf("failed to fetch endpoints: %v", err)
149-
}
150-
151-
// Check if service exists
152-
serviceEndpoint, ok := endpointsMap[service]
153-
if !ok {
154-
return fmt.Errorf("service '%s' not found", service)
155-
}
156-
157-
// Fetch service resources
158-
resources, err := fetchServiceResources(service, serviceEndpoint, nil)
159-
if err != nil {
160-
return fmt.Errorf("failed to fetch service resources: %v", err)
161-
}
162-
163-
// Find the resource and check if the verb is valid
164-
resourceFound := false
165-
verbFound := false
166-
167-
for _, row := range resources {
168-
if row[2] == resource {
169-
resourceFound = true
170-
verbs := strings.Split(row[1], ", ")
171-
for _, v := range verbs {
172-
if v == verb {
173-
verbFound = true
174-
break
175-
}
176-
}
177-
break
178-
}
179-
}
180-
181-
if !resourceFound {
182-
return fmt.Errorf("resource '%s' not found in service '%s'", resource, service)
183-
}
184-
185-
if !verbFound {
186-
return fmt.Errorf("verb '%s' not found for resource '%s' in service '%s'", verb, resource, service)
187-
}
188-
189-
return nil
190-
}
191-
192-
func addAlias(key, value string) error {
193-
home, err := os.UserHomeDir()
194-
if err != nil {
195-
return fmt.Errorf("failed to get home directory: %v", err)
196-
}
197-
198-
settingPath := filepath.Join(home, ".cfctl", "setting.yaml")
199-
200-
data, err := os.ReadFile(settingPath)
201-
if err != nil && !os.IsNotExist(err) {
202-
return fmt.Errorf("failed to read config: %v", err)
203-
}
204-
205-
var config map[string]interface{}
206-
if err := yaml.Unmarshal(data, &config); err != nil {
207-
return fmt.Errorf("failed to parse config: %v", err)
208-
}
209-
210-
aliases, ok := config["aliases"].(map[string]interface{})
211-
if !ok {
212-
aliases = make(map[string]interface{})
213-
}
214-
215-
delete(config, "aliases")
216-
aliases[key] = value
217-
218-
newData, err := yaml.Marshal(config)
219-
if err != nil {
220-
return fmt.Errorf("failed to encode config: %v", err)
221-
}
222-
223-
aliasData, err := yaml.Marshal(map[string]interface{}{"aliases": aliases})
224-
if err != nil {
225-
return fmt.Errorf("failed to encode aliases: %v", err)
226-
}
227-
228-
finalData := append(newData, aliasData...)
229-
230-
if err := os.WriteFile(settingPath, finalData, 0644); err != nil {
231-
return fmt.Errorf("failed to write config: %v", err)
232-
}
233-
234-
return nil
235-
}
236-
237-
// Function to remove an alias
238-
func removeAlias(key string) error {
239-
home, err := os.UserHomeDir()
240-
if err != nil {
241-
return fmt.Errorf("failed to get home directory: %v", err)
242-
}
243-
244-
settingPath := filepath.Join(home, ".cfctl", "setting.yaml")
245-
246-
data, err := os.ReadFile(settingPath)
247-
if err != nil {
248-
return fmt.Errorf("failed to read config: %v", err)
249-
}
250-
251-
var config map[string]interface{}
252-
if err := yaml.Unmarshal(data, &config); err != nil {
253-
return fmt.Errorf("failed to parse config: %v", err)
254-
}
255-
256-
aliases, ok := config["aliases"].(map[string]interface{})
257-
if !ok || aliases[key] == nil {
258-
return fmt.Errorf("alias '%s' not found", key)
259-
}
260-
261-
delete(aliases, key)
262-
delete(config, "aliases")
263-
264-
// YAML 인코딩
265-
newData, err := yaml.Marshal(config)
266-
if err != nil {
267-
return fmt.Errorf("failed to encode config: %v", err)
268-
}
269-
270-
if len(aliases) > 0 {
271-
aliasData, err := yaml.Marshal(map[string]interface{}{"aliases": aliases})
272-
if err != nil {
273-
return fmt.Errorf("failed to encode aliases: %v", err)
274-
}
275-
newData = append(newData, aliasData...)
276-
}
277-
278-
if err := os.WriteFile(settingPath, newData, 0644); err != nil {
279-
return fmt.Errorf("failed to write config: %v", err)
280-
}
281-
282-
return nil
283-
}
284-
285-
func ListAliases() (map[string]string, error) {
286-
home, err := os.UserHomeDir()
287-
if err != nil {
288-
return nil, fmt.Errorf("failed to get home directory: %v", err)
289-
}
290-
291-
settingPath := filepath.Join(home, ".cfctl", "setting.yaml")
292-
v := viper.New()
293-
v.SetConfigFile(settingPath)
294-
v.SetConfigType("yaml")
295-
296-
if err := v.ReadInConfig(); err != nil {
297-
if os.IsNotExist(err) {
298-
return make(map[string]string), nil
299-
}
300-
return nil, fmt.Errorf("failed to read config: %v", err)
301-
}
302-
303-
aliases := v.GetStringMapString("aliases")
304-
if aliases == nil {
305-
return make(map[string]string), nil
306-
}
307-
308-
return aliases, nil
309-
}
310-
311109
func init() {
312110
AliasCmd.AddCommand(addAliasCmd)
313111
AliasCmd.AddCommand(removeAliasCmd)
314112
AliasCmd.AddCommand(listAliasCmd)
315113

316-
// Remove service flag as it's no longer needed
114+
addAliasCmd.Flags().StringP("service", "s", "", "Service to add alias for")
317115
addAliasCmd.Flags().StringP("key", "k", "", "Alias key to add")
318-
addAliasCmd.Flags().StringP("value", "v", "", "Command to execute (e.g., \"identity list User\")")
116+
addAliasCmd.Flags().StringP("value", "v", "", "Command to execute (e.g., \"list User\")")
117+
addAliasCmd.MarkFlagRequired("service")
319118
addAliasCmd.MarkFlagRequired("key")
320119
addAliasCmd.MarkFlagRequired("value")
321120

121+
removeAliasCmd.Flags().StringP("service", "s", "", "Service to remove alias from")
322122
removeAliasCmd.Flags().StringP("key", "k", "", "Alias key to remove")
123+
removeAliasCmd.MarkFlagRequired("service")
323124
removeAliasCmd.MarkFlagRequired("key")
324125
}

0 commit comments

Comments
 (0)