github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/cmd/swift.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/url" 9 "os" 10 "strconv" 11 12 "github.com/cozy/cozy-stack/client/request" 13 "github.com/spf13/cobra" 14 ) 15 16 var flagSwiftObjectContentType string 17 var flagShowDomains bool 18 19 var swiftCmdGroup = &cobra.Command{ 20 Use: "swift <command>", 21 Short: "Interact directly with OpenStack Swift object storage", 22 RunE: func(cmd *cobra.Command, args []string) error { 23 return cmd.Usage() 24 }, 25 } 26 27 var lsLayoutsCmd = &cobra.Command{ 28 Use: "ls-layouts", 29 Short: `Count layouts by types (v3a, v3b, unknown)`, 30 Example: "$ cozy-stack swift ls-layouts", 31 RunE: func(cmd *cobra.Command, args []string) error { 32 ac := newAdminClient() 33 values := url.Values{} 34 values.Add("show_domains", strconv.FormatBool(flagShowDomains)) 35 res, err := ac.Req(&request.Options{ 36 Method: "GET", 37 Path: "/swift/layouts", 38 Queries: values, 39 }) 40 if err != nil { 41 return err 42 } 43 defer res.Body.Close() 44 45 var buf interface{} 46 if err := json.NewDecoder(res.Body).Decode(&buf); err != nil { 47 return err 48 } 49 json, err := json.MarshalIndent(buf, "", " ") 50 if err != nil { 51 return err 52 } 53 54 fmt.Println(string(json)) 55 return nil 56 }, 57 } 58 59 var swiftGetCmd = &cobra.Command{ 60 Use: "get <domain> <object-name>", 61 Aliases: []string{"download"}, 62 RunE: func(cmd *cobra.Command, args []string) error { 63 if len(args) < 2 { 64 return cmd.Usage() 65 } 66 67 ac := newAdminClient() 68 path := fmt.Sprintf("/swift/vfs/%s", url.PathEscape(args[1])) 69 res, err := ac.Req(&request.Options{ 70 Method: "GET", 71 Path: path, 72 Domain: args[0], 73 }) 74 if err != nil { 75 return err 76 } 77 defer res.Body.Close() 78 79 // Read the body and print it 80 _, err = io.Copy(os.Stdout, res.Body) 81 return err 82 }, 83 } 84 85 var swiftPutCmd = &cobra.Command{ 86 Use: "put <domain> <object-name>", 87 Aliases: []string{"upload"}, 88 Long: `cozy-stack swift put can be used to create or update an object in 89 the swift container associated to the given domain. The content of the file is 90 expected on the standard input.`, 91 RunE: func(cmd *cobra.Command, args []string) error { 92 if len(args) < 2 { 93 return cmd.Usage() 94 } 95 96 ac := newAdminClient() 97 buf := new(bytes.Buffer) 98 99 _, err := io.Copy(buf, os.Stdin) 100 if err != nil { 101 return err 102 } 103 104 _, err = ac.Req(&request.Options{ 105 Method: "PUT", 106 Path: fmt.Sprintf("/swift/vfs/%s", url.PathEscape(args[1])), 107 Body: bytes.NewReader(buf.Bytes()), 108 Domain: args[0], 109 Headers: map[string]string{ 110 "Content-Type": flagSwiftObjectContentType, 111 }, 112 }) 113 if err != nil { 114 return err 115 } 116 117 fmt.Println("Object has been added to swift") 118 return nil 119 }, 120 } 121 122 var swiftDeleteCmd = &cobra.Command{ 123 Use: "rm <domain> <object-name>", 124 Aliases: []string{"delete"}, 125 RunE: func(cmd *cobra.Command, args []string) error { 126 if len(args) < 2 { 127 return cmd.Usage() 128 } 129 130 ac := newAdminClient() 131 path := fmt.Sprintf("/swift/vfs/%s", url.PathEscape(args[1])) 132 _, err := ac.Req(&request.Options{ 133 Method: "DELETE", 134 Path: path, 135 Domain: args[0], 136 }) 137 138 return err 139 }, 140 } 141 142 var swiftLsCmd = &cobra.Command{ 143 Use: "ls <domain>", 144 Aliases: []string{"list"}, 145 RunE: func(cmd *cobra.Command, args []string) error { 146 if len(args) < 1 { 147 return cmd.Usage() 148 } 149 150 type resStruct struct { 151 ObjectNameList []string `json:"objects_names"` 152 } 153 154 ac := newAdminClient() 155 res, err := ac.Req(&request.Options{ 156 Method: "GET", 157 Path: "/swift/vfs", 158 Domain: args[0], 159 }) 160 if err != nil { 161 return err 162 } 163 164 names := resStruct{} 165 err = json.NewDecoder(res.Body).Decode(&names) 166 if err != nil { 167 return err 168 } 169 170 for _, name := range names.ObjectNameList { 171 fmt.Println(name) 172 } 173 174 return nil 175 }, 176 } 177 178 func init() { 179 swiftPutCmd.Flags().StringVar(&flagSwiftObjectContentType, "content-type", "", "Specify a Content-Type for the created object") 180 lsLayoutsCmd.Flags().BoolVar(&flagShowDomains, "show-domains", false, "Show the domains along the counter") 181 182 swiftCmdGroup.AddCommand(swiftGetCmd) 183 swiftCmdGroup.AddCommand(swiftPutCmd) 184 swiftCmdGroup.AddCommand(swiftDeleteCmd) 185 swiftCmdGroup.AddCommand(swiftLsCmd) 186 swiftCmdGroup.AddCommand(lsLayoutsCmd) 187 188 RootCmd.AddCommand(swiftCmdGroup) 189 }