Skip to content

Commit 1ba84ce

Browse files
committed
update irictl-volume to support volumesnapshot operations
1 parent 1ac7ce6 commit 1ba84ce

File tree

10 files changed

+282
-3
lines changed

10 files changed

+282
-3
lines changed

irictl-volume/cmd/irictl-volume/irictlvolume/common/common.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ func NewOutputOptions() *clicommon.OutputOptions {
5858
}
5959

6060
var (
61-
VolumeAliases = []string{"volumes", "vol", "vols"}
61+
VolumeAliases = []string{"volumes", "vol", "vols"}
62+
VolumeSnapshotAliases = []string{"volumesnapshots", "volsnap", "volsnaps"}
6263
)

irictl-volume/cmd/irictl-volume/irictlvolume/create/create.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package create
66
import (
77
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/common"
88
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/create/volume"
9+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/create/volumesnapshot"
910
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
1011
"github.com/spf13/cobra"
1112
)
@@ -17,6 +18,7 @@ func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cob
1718

1819
cmd.AddCommand(
1920
volume.Command(streams, clientFactory),
21+
volumesnapshot.Command(streams, clientFactory),
2022
)
2123

2224
return cmd
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package volumesnapshot
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"os"
10+
11+
iri "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
12+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/common"
13+
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
14+
"github.com/ironcore-dev/ironcore/irictl/decoder"
15+
"github.com/ironcore-dev/ironcore/irictl/renderer"
16+
"github.com/spf13/cobra"
17+
"github.com/spf13/pflag"
18+
ctrl "sigs.k8s.io/controller-runtime"
19+
)
20+
21+
type Options struct {
22+
Filename string
23+
}
24+
25+
func (o *Options) AddFlags(fs *pflag.FlagSet) {
26+
fs.StringVarP(&o.Filename, "filename", "f", o.Filename, "Path to a file to read.")
27+
}
28+
29+
func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cobra.Command {
30+
var (
31+
outputOpts = common.NewOutputOptions()
32+
opts Options
33+
)
34+
35+
cmd := &cobra.Command{
36+
Use: "volumesnapshot",
37+
Aliases: common.VolumeSnapshotAliases,
38+
RunE: func(cmd *cobra.Command, args []string) error {
39+
ctx := cmd.Context()
40+
log := ctrl.LoggerFrom(ctx)
41+
42+
client, cleanup, err := clientFactory.New()
43+
if err != nil {
44+
return err
45+
}
46+
defer func() {
47+
if err := cleanup(); err != nil {
48+
log.Error(err, "Error cleaning up")
49+
}
50+
}()
51+
52+
r, err := outputOpts.RendererOrNil()
53+
if err != nil {
54+
return err
55+
}
56+
57+
return Run(ctx, streams, client, r, opts)
58+
},
59+
}
60+
61+
outputOpts.AddFlags(cmd.Flags())
62+
opts.AddFlags(cmd.Flags())
63+
64+
return cmd
65+
}
66+
67+
func Run(ctx context.Context, streams clicommon.Streams, client iri.VolumeRuntimeClient, r renderer.Renderer, opts Options) error {
68+
data, err := clicommon.ReadFileOrReader(opts.Filename, os.Stdin)
69+
if err != nil {
70+
return err
71+
}
72+
73+
volumeSnapshot := &iri.VolumeSnapshot{}
74+
if err := decoder.Decode(data, volumeSnapshot); err != nil {
75+
return err
76+
}
77+
78+
res, err := client.CreateVolumeSnapshot(ctx, &iri.CreateVolumeSnapshotRequest{VolumeSnapshot: volumeSnapshot})
79+
if err != nil {
80+
return err
81+
}
82+
83+
if r != nil {
84+
return r.Render(res.VolumeSnapshot, streams.Out)
85+
}
86+
87+
_, _ = fmt.Fprintf(streams.Out, "Created volume snapshot %s\n", res.VolumeSnapshot.Metadata.Id)
88+
return nil
89+
}

irictl-volume/cmd/irictl-volume/irictlvolume/delete/delete.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package delete
66
import (
77
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/common"
88
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/delete/volume"
9+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/delete/volumesnapshot"
910
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
1011
"github.com/spf13/cobra"
1112
)
@@ -17,6 +18,7 @@ func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cob
1718

1819
cmd.AddCommand(
1920
volume.Command(streams, clientFactory),
21+
volumesnapshot.Command(streams, clientFactory),
2022
)
2123

2224
return cmd
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package volumesnapshot
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
iri "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
11+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/common"
12+
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
13+
"github.com/spf13/cobra"
14+
"google.golang.org/grpc/codes"
15+
"google.golang.org/grpc/status"
16+
ctrl "sigs.k8s.io/controller-runtime"
17+
)
18+
19+
func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cobra.Command {
20+
cmd := &cobra.Command{
21+
Use: "volumesnapshot id [ids...]",
22+
Aliases: common.VolumeSnapshotAliases,
23+
Args: cobra.MinimumNArgs(1),
24+
RunE: func(cmd *cobra.Command, args []string) error {
25+
ctx := cmd.Context()
26+
log := ctrl.LoggerFrom(ctx)
27+
28+
client, cleanup, err := clientFactory.New()
29+
if err != nil {
30+
return err
31+
}
32+
defer func() {
33+
if err := cleanup(); err != nil {
34+
log.Error(err, "Error cleaning up")
35+
}
36+
}()
37+
38+
ids := args
39+
40+
return Run(cmd.Context(), streams, client, ids)
41+
},
42+
}
43+
44+
return cmd
45+
}
46+
47+
func Run(ctx context.Context, streams clicommon.Streams, client iri.VolumeRuntimeClient, ids []string) error {
48+
for _, id := range ids {
49+
if _, err := client.DeleteVolumeSnapshot(ctx, &iri.DeleteVolumeSnapshotRequest{
50+
VolumeSnapshotId: id,
51+
}); err != nil {
52+
if status.Code(err) != codes.NotFound {
53+
return fmt.Errorf("error deleting volume snapshot %s: %w", id, err)
54+
}
55+
56+
_, _ = fmt.Fprintf(streams.Out, "VolumeSnapshot %s not found\n", id)
57+
} else {
58+
_, _ = fmt.Fprintf(streams.Out, "VolumeSnapshot %s deleted\n", id)
59+
}
60+
}
61+
return nil
62+
}

irictl-volume/cmd/irictl-volume/irictlvolume/get/get.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/get/event"
99
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/get/status"
1010
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/get/volume"
11+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/get/volumesnapshot"
1112
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
1213
"github.com/spf13/cobra"
1314
)
@@ -21,6 +22,7 @@ func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cob
2122
volume.Command(streams, clientFactory),
2223
status.Command(streams, clientFactory),
2324
event.Command(streams, clientFactory),
25+
volumesnapshot.Command(streams, clientFactory),
2426
)
2527

2628
return cmd
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package volumesnapshot
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
iri "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
11+
"github.com/ironcore-dev/ironcore/irictl-volume/cmd/irictl-volume/irictlvolume/common"
12+
clicommon "github.com/ironcore-dev/ironcore/irictl/cmd"
13+
"github.com/ironcore-dev/ironcore/irictl/renderer"
14+
"github.com/spf13/cobra"
15+
"github.com/spf13/pflag"
16+
ctrl "sigs.k8s.io/controller-runtime"
17+
)
18+
19+
type Options struct {
20+
}
21+
22+
func (o *Options) AddFlags(fs *pflag.FlagSet) {
23+
}
24+
25+
func Command(streams clicommon.Streams, clientFactory common.ClientFactory) *cobra.Command {
26+
var (
27+
opts Options
28+
outputOpts = common.NewOutputOptions()
29+
)
30+
31+
cmd := &cobra.Command{
32+
Use: "volumesnapshot",
33+
Aliases: common.VolumeAliases,
34+
RunE: func(cmd *cobra.Command, args []string) error {
35+
ctx := cmd.Context()
36+
log := ctrl.LoggerFrom(ctx)
37+
38+
client, cleanup, err := clientFactory.New()
39+
if err != nil {
40+
return err
41+
}
42+
defer func() {
43+
if err := cleanup(); err != nil {
44+
log.Error(err, "Error cleaning up")
45+
}
46+
}()
47+
48+
render, err := outputOpts.Renderer("table")
49+
if err != nil {
50+
return err
51+
}
52+
53+
return Run(cmd.Context(), streams, client, render, opts)
54+
},
55+
}
56+
57+
outputOpts.AddFlags(cmd.Flags())
58+
opts.AddFlags(cmd.Flags())
59+
60+
return cmd
61+
}
62+
63+
func Run(ctx context.Context, streams clicommon.Streams, client iri.VolumeRuntimeClient, render renderer.Renderer, opts Options) error {
64+
res, err := client.ListVolumeSnapshots(ctx, &iri.ListVolumeSnapshotsRequest{})
65+
if err != nil {
66+
return fmt.Errorf("error listing volume snapshots: %w", err)
67+
}
68+
69+
return render.Render(res.VolumeSnapshots, streams.Out)
70+
}

irictl-volume/config/samples/volume.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ metadata:
44
labels:
55
bar: baz
66
spec:
7-
class: volumeclass-sample
7+
class: experimental
88
image: ghcr.io/ironcore-dev/ironcore-image/gardenlinux:latest
99
resources:
10-
storage_bytes: 1073741824
10+
storage_bytes: 1073741824
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
metadata:
2+
annotations:
3+
foo: bar
4+
labels:
5+
bar: baz
6+
spec:
7+
volume_id: 2992076108895c9fb7a3f46ccac649763ed3370922ed5dd33c1695cb5f770cd
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package tableconverters
5+
6+
import (
7+
"time"
8+
9+
iri "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
10+
"github.com/ironcore-dev/ironcore/irictl/api"
11+
"github.com/ironcore-dev/ironcore/irictl/tableconverter"
12+
"k8s.io/apimachinery/pkg/util/duration"
13+
)
14+
15+
var (
16+
volumeSnapshotHeaders = []api.Header{
17+
{Name: "ID"},
18+
{Name: "VolumeID"},
19+
{Name: "State"},
20+
{Name: "Age"},
21+
}
22+
)
23+
24+
var (
25+
VolumeSnapshot = tableconverter.Funcs[*iri.VolumeSnapshot]{
26+
Headers: tableconverter.Headers(volumeSnapshotHeaders),
27+
Rows: tableconverter.SingleRowFrom(func(volumeSnapshot *iri.VolumeSnapshot) (api.Row, error) {
28+
return api.Row{
29+
volumeSnapshot.Metadata.Id,
30+
volumeSnapshot.Spec.VolumeId,
31+
volumeSnapshot.Status.State.String(),
32+
duration.HumanDuration(time.Since(time.Unix(0, volumeSnapshot.Metadata.CreatedAt))),
33+
}, nil
34+
}),
35+
}
36+
VolumeSnapshotSlice = tableconverter.SliceFuncs[*iri.VolumeSnapshot](VolumeSnapshot)
37+
)
38+
39+
func init() {
40+
RegistryBuilder.Register(
41+
tableconverter.ToTagAndTypedAny[*iri.VolumeSnapshot](VolumeSnapshot),
42+
tableconverter.ToTagAndTypedAny[[]*iri.VolumeSnapshot](VolumeSnapshotSlice),
43+
)
44+
}

0 commit comments

Comments
 (0)