github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/cmd/settings.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "os" 9 "sort" 10 "strings" 11 12 "github.com/cozy/cozy-stack/client" 13 "github.com/cozy/cozy-stack/client/request" 14 "github.com/cozy/cozy-stack/pkg/consts" 15 "github.com/spf13/cobra" 16 ) 17 18 var settingsCmd = &cobra.Command{ 19 Use: "settings [settings]", 20 Short: "Display and update settings", 21 Long: ` 22 cozy-stack settings displays the settings. 23 24 It can also take a list of settings to update. 25 26 If you give a blank value, the setting will be removed. 27 `, 28 Example: "$ cozy-stack settings --domain cozy.localhost:8080 context:beta,public_name:John,to_remove:", 29 RunE: func(cmd *cobra.Command, args []string) error { 30 if flagDomain == "" { 31 errPrintfln("%s", errMissingDomain) 32 return cmd.Usage() 33 } 34 c := newClient(flagDomain, consts.Settings) 35 res, err := c.Req(&request.Options{ 36 Method: "GET", 37 Path: "/settings/instance", 38 }) 39 if err != nil { 40 return err 41 } 42 defer res.Body.Close() 43 var obj map[string]interface{} 44 if err = json.NewDecoder(res.Body).Decode(&obj); err != nil { 45 return err 46 } 47 if len(args) > 0 { 48 obj, err = updateSettings(c, obj, args[0]) 49 if err != nil { 50 return err 51 } 52 } 53 printSettings(obj) 54 return nil 55 }, 56 } 57 58 func printSettings(obj map[string]interface{}) { 59 data, ok := obj["data"].(map[string]interface{}) 60 if !ok { 61 return 62 } 63 attrs, ok := data["attributes"].(map[string]interface{}) 64 if !ok { 65 return 66 } 67 keys := make([]string, 0, len(attrs)) 68 for k := range attrs { 69 keys = append(keys, k) 70 } 71 sort.Strings(keys) 72 for _, k := range keys { 73 fmt.Fprintf(os.Stdout, "- %s: %v\n", k, attrs[k]) 74 } 75 } 76 77 func updateSettings(c *client.Client, obj map[string]interface{}, args string) (map[string]interface{}, error) { 78 data, ok := obj["data"].(map[string]interface{}) 79 if !ok { 80 return nil, errors.New("data not found") 81 } 82 attrs, ok := data["attributes"].(map[string]interface{}) 83 if !ok { 84 return nil, errors.New("attributes not found") 85 } 86 for _, arg := range strings.Split(args, ",") { 87 parts := strings.SplitN(arg, ":", 2) 88 k := parts[0] 89 if len(parts) < 2 || parts[1] == "" { 90 delete(attrs, k) 91 } else { 92 attrs[k] = parts[1] 93 } 94 } 95 delete(obj, "links") 96 buf, err := json.Marshal(obj) 97 if err != nil { 98 return nil, err 99 } 100 body := bytes.NewReader(buf) 101 res, err := c.Req(&request.Options{ 102 Method: "PUT", 103 Path: "/settings/instance", 104 Body: body, 105 }) 106 if err != nil { 107 return nil, err 108 } 109 defer res.Body.Close() 110 err = json.NewDecoder(res.Body).Decode(&obj) 111 return obj, err 112 } 113 114 func init() { 115 settingsCmd.PersistentFlags().StringVar(&flagDomain, "domain", cozyDomain(), "specify the domain name of the instance") 116 RootCmd.AddCommand(settingsCmd) 117 }