Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- storage: add bucket lifecycle support #847

## 1.95.2

### Features
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func newDepActionsServer(t *testing.T) *depActionsServer {
}
if len(parts) == 2 && parts[1] == "scale" && r.Method == http.MethodPost {
b, _ := io.ReadAll(r.Body)
r.Body.Close()
_ = r.Body.Close()
ts.lastScaleBody = string(b)
testutils.WriteJSON(t, w, http.StatusOK, v3.Operation{ID: v3.UUID("op-deploy-scale"), State: v3.OperationStateSuccess})
return
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (c *DeploymentCreateCmd) CmdRun(_ *cobra.Command, _ []string) error {
return err
}
if !globalstate.Quiet {
fmt.Fprintln(os.Stdout, "Deployment created.")
_, _ = fmt.Fprintln(os.Stdout, "Deployment created.")
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/aiservices/deployment/deployment_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestDeploymentCreateWithInferenceEngineParameters(t *testing.T) {
return
}
body, _ := io.ReadAll(r.Body)
r.Body.Close()
_ = r.Body.Close()
if err := json.Unmarshal(body, &capturedRequest); err != nil {
t.Fatalf("failed to unmarshal request: %v", err)
}
Expand Down Expand Up @@ -115,7 +115,7 @@ func TestDeploymentCreateWithInferenceEngineVersion(t *testing.T) {
return
}
body, _ := io.ReadAll(r.Body)
r.Body.Close()
_ = r.Body.Close()
if err := json.Unmarshal(body, &capturedRequest); err != nil {
t.Fatalf("failed to unmarshal request: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (c *DeploymentDeleteCmd) CmdRun(_ *cobra.Command, _ []string) error {
}

if !globalstate.Quiet {
fmt.Fprintln(os.Stdout, "Deployment(s) deleted.")
_, _ = fmt.Fprintln(os.Stdout, "Deployment(s) deleted.")
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (c *DeploymentLogsCmd) CmdRun(_ *cobra.Command, _ []string) error {

if !globalstate.Quiet {
for _, entry := range resp.Logs {
fmt.Fprintln(os.Stdout, entry.Message)
_, _ = fmt.Fprintln(os.Stdout, entry.Message)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (c *DeploymentUpdateCmd) CmdRun(_ *cobra.Command, _ []string) error {
}

if !globalstate.Quiet {
fmt.Fprintln(os.Stdout, "Deployment updated.")
_, _ = fmt.Fprintln(os.Stdout, "Deployment updated.")
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/deployment/deployment_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestDeploymentUpdate(t *testing.T) {
if r.Method == http.MethodPatch {
capturedID = path.Base(r.URL.Path)
body, _ := io.ReadAll(r.Body)
r.Body.Close()
_ = r.Body.Close()
if err := json.Unmarshal(body, &capturedRequest); err != nil {
t.Fatalf("failed to unmarshal request: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/model/model_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (c *ModelCreateCmd) CmdRun(_ *cobra.Command, _ []string) error {
return err
}
if !globalstate.Quiet {
fmt.Fprintln(os.Stdout, "Model created.")
_, _ = fmt.Fprintln(os.Stdout, "Model created.")
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/aiservices/model/model_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (c *ModelDeleteCmd) CmdRun(_ *cobra.Command, _ []string) error {
}

if !globalstate.Quiet {
fmt.Fprintln(os.Stdout, "Model(s) deleted.")
_, _ = fmt.Fprintln(os.Stdout, "Model(s) deleted.")
}
return nil
}
Expand Down
18 changes: 10 additions & 8 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ type cliCommand interface {
// specified from the cliCommand.
func cliCommandFlagName(c cliCommand, field interface{}) (string, error) {
fieldValue := reflect.ValueOf(field)
if fieldValue.Kind() != reflect.Ptr || fieldValue.IsNil() {
if fieldValue.Kind() != reflect.Pointer || fieldValue.IsNil() {
return "", fmt.Errorf("field must be a non-nil pointer value")
}

Expand Down Expand Up @@ -215,7 +215,7 @@ func cliCommandFlagSet(c cliCommand) (*pflag.FlagSet, error) {
fs := pflag.NewFlagSet("", pflag.ExitOnError)
cv := reflect.ValueOf(c)

if cv.Kind() == reflect.Ptr {
if cv.Kind() == reflect.Pointer {
cv = cv.Elem()
}

Expand Down Expand Up @@ -333,7 +333,7 @@ func cliCommandUse(c cliCommand) (string, error) {

cv := reflect.ValueOf(c)

if cv.Kind() == reflect.Ptr {
if cv.Kind() == reflect.Pointer {
cv = cv.Elem()
}

Expand Down Expand Up @@ -404,7 +404,7 @@ func cliCommandUse(c cliCommand) (string, error) {
func CliCommandDefaultPreRun(c cliCommand, cmd *cobra.Command, args []string) error { //nolint:gocyclo
cv := reflect.ValueOf(c)

if cv.Kind() == reflect.Ptr {
if cv.Kind() == reflect.Pointer {
cv = cv.Elem()
}

Expand All @@ -425,7 +425,8 @@ func CliCommandDefaultPreRun(c cliCommand, cmd *cobra.Command, args []string) er
if argMode, ok := cTypeField.Tag.Lookup("cli-arg"); ok {
switch t := cTypeField.Type.Kind(); t {
case reflect.Int64:
if argMode == "#" {
switch argMode {
case "#":
// Required arg
if argp >= len(args) {
return fmt.Errorf("missing arguments, run with --help for usage")
Expand All @@ -436,7 +437,7 @@ func CliCommandDefaultPreRun(c cliCommand, cmd *cobra.Command, args []string) er
return fmt.Errorf("invalid value %q", args[argp])
}
cField.SetInt(int64(argVal))
} else if argMode == "?" {
case "?":
// Optional arg
if argp < len(args) {
argVal, err := strconv.Atoi(args[argp])
Expand All @@ -448,13 +449,14 @@ func CliCommandDefaultPreRun(c cliCommand, cmd *cobra.Command, args []string) er
}

case reflect.String:
if argMode == "#" {
switch argMode {
case "#":
// Required arg
if argp >= len(args) {
return fmt.Errorf("missing arguments, run with --help for usage")
}
cField.SetString(args[argp])
} else if argMode == "?" {
case "?":
// Optional arg
if argp < len(args) {
cField.SetString(args[argp])
Expand Down
6 changes: 3 additions & 3 deletions cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func statusShow() error {

buf := bytes.NewBuffer(nil)
st := table.NewEmbeddedTable(buf)
st.Table.AppendBulk(global)
st.AppendBulk(global)
st.Render()
t.Append([]string{"Services", buf.String()})
buf.Reset()
Expand All @@ -71,7 +71,7 @@ func statusShow() error {
// Show incidents currently taking place
if len(incidents) > 0 {
it := table.NewEmbeddedTable(buf)
it.Table.AppendBulk(incidents)
it.AppendBulk(incidents)
it.Render()
} else {
buf = bytes.NewBuffer([]byte("n/a"))
Expand All @@ -86,7 +86,7 @@ func statusShow() error {
}
if len(maintenances) > 0 {
mt := table.NewEmbeddedTable(buf)
mt.Table.AppendBulk(maintenances)
mt.AppendBulk(maintenances)
mt.Render()
} else {
buf = bytes.NewBuffer([]byte("n/a"))
Expand Down
21 changes: 21 additions & 0 deletions cmd/storage/storage_bucket_lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package storage

import (
exocmd "github.com/exoscale/cli/cmd"
"github.com/spf13/cobra"
)

func init() {
storageBucketLifecycleCmd.Flags().StringP(exocmd.ZoneFlagLong, exocmd.ZoneFlagShort, "", exocmd.ZoneFlagMsg)
storageBucketCmd.AddCommand(storageBucketLifecycleCmd)
}

var storageBucketLifecycleCmd = &cobra.Command{
Use: "lifecycle",
Short: "Object Storage Bucket lifecycle management",
Long: storageBucketLifecycleCmdLongHelp(),
}

var storageBucketLifecycleCmdLongHelp = func() string {
return "Object Storage Bucket lifecycle management"
}
48 changes: 48 additions & 0 deletions cmd/storage/storage_bucket_lifecycle_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package storage

import (
"fmt"
"strings"

"github.com/exoscale/cli/pkg/storage/sos"

exocmd "github.com/exoscale/cli/cmd"
"github.com/spf13/cobra"
)

func init() {
storageBucketLifecycleDeleteCmd.Flags().StringP(exocmd.ZoneFlagLong, exocmd.ZoneFlagShort, "", exocmd.ZoneFlagMsg)
storageBucketLifecycleCmd.AddCommand(storageBucketLifecycleDeleteCmd)
}

var storageBucketLifecycleDeleteCmd = &cobra.Command{
Use: "delete sos://BUCKET",
Short: "Delete lifecycle configuration",
Args: cobra.ExactArgs(1),
PreRunE: func(c *cobra.Command, args []string) error {

args[0] = strings.TrimPrefix(args[0], sos.BucketPrefix)

exocmd.CmdSetZoneFlagFromDefault(c)
return exocmd.CmdCheckRequiredFlags(c, []string{exocmd.ZoneFlagLong})
},
RunE: func(c *cobra.Command, args []string) error {
bucket := args[0]

zone, err := c.Flags().GetString(exocmd.ZoneFlagLong)
if err != nil {
return err
}

storage, err := sos.NewStorageClient(
exocmd.GContext,
sos.ClientOptWithZone(zone),
)
if err != nil {
return fmt.Errorf("unable to initialize storage client: %w", err)
}

err = storage.DeleteBucketLifecycle(exocmd.GContext, bucket)
return err
},
}
78 changes: 78 additions & 0 deletions cmd/storage/storage_bucket_lifecycle_set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package storage

import (
"encoding/json"
"fmt"
"os"
"strings"

exocmd "github.com/exoscale/cli/cmd"
"github.com/exoscale/cli/pkg/storage/sos"
"github.com/spf13/cobra"
)

func init() {
storageBucketLifecycleSetCmd.Flags().StringP(exocmd.ZoneFlagLong, exocmd.ZoneFlagShort, "", exocmd.ZoneFlagMsg)
storageBucketLifecycleCmd.AddCommand(storageBucketLifecycleSetCmd)
}

var storageBucketLifecycleSetCmd = &cobra.Command{
Use: "set sos://BUCKET path/to/lifecycle.json",
Short: "Set lifecycle configuration",
Long: `Set a lifecycle configuration for a bucket.

Example of a valid lifecycle configuration:
{
"Rules": [
{
"Status": "Enabled",
"Expiration": { "Days": 30 },
"Filter": { "Prefix": "" },
"ID": "expire-after-30-days"
}
]
}`,
Args: cobra.ExactArgs(2),
PreRunE: func(cmd *cobra.Command, args []string) error {

args[0] = strings.TrimPrefix(args[0], sos.BucketPrefix)

exocmd.CmdSetZoneFlagFromDefault(cmd)
return exocmd.CmdCheckRequiredFlags(cmd, []string{exocmd.ZoneFlagLong})
},
RunE: func(cmd *cobra.Command, args []string) error {

var configuration sos.BucketLifecycleConf

confFile, err := os.Open(args[1])
if err != nil {
return err
}

jsonParsr := json.NewDecoder(confFile)
if err = jsonParsr.Decode(&configuration); err != nil {
return err
}

bucket := args[0]

zone, err := cmd.Flags().GetString(exocmd.ZoneFlagLong)
if err != nil {
return err
}

storage, err := sos.NewStorageClient(
exocmd.GContext,
sos.ClientOptWithZone(zone),
)
if err != nil {
return fmt.Errorf("unable to initialize storage client: %w", err)
}

s3conf := configuration.ToS3()

err = storage.PutBucketLifecycle(exocmd.GContext, bucket, s3conf)

return err
},
}
Loading
Loading