mirror of
https://github.com/kastenhq/kubestr.git
synced 2024-12-14 11:57:56 +00:00
Adding --show-tree flag to both "./kubestr browse pvc" & "./kubestr browse snapshot" commands (#278)
* Adding the kubestr browse pvc command. Handling kubestr browse support for backward compatibility. * Adding browse snapshot command. Updating browse command to browse pvc command. * chore(deps): bump github/codeql-action in the github-actions group (#272) Bumps the github-actions group with 1 update: [github/codeql-action](https://github.com/github/codeql-action). Updates `github/codeql-action` from 3.25.12 to 3.25.13 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](4fa2a79536...2d790406f5
) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump docker/build-push-action in the docker group (#273) Bumps the docker group with 1 update: [docker/build-push-action](https://github.com/docker/build-push-action). Updates `docker/build-push-action` from 6.3.0 to 6.4.1 - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](1a162644f9...1ca370b3a9
) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Adding --show-tree flag for browse snapshot & browse pvc commands * Removing unused snapshot function parameter in cleanup * Adding KubeExecutor Exec helper function to execute tree command * Adding --show-tree logic in pvc_inspector.go * Adding --show-tree logic in snapshot_inspector.go * Printing out the tree structure for --show-tree * Updating mock tests for new code changes * Updating mount path in container args for creating a browse pod * Updating the CSITestSuite.TestCreateInspectorApplication for changes in the mount path * Adding Deprecated msg to the 'browse' command * Adding mock tests for SnapshotBrowserStepper * Adding fake tests for snapshot_inspector.go * Renamed testcase CSITestSuite.TestCreateInspectorApplication to TestCreateInspectorApplicationForPVC * Adding snapshot_inspector_steps_test.go * Updating mock tests for new code changes * Updating the mount paths in CSITestSuite.TestCreateInspectorApplicationForSnapshot * Updating Deprecated msg for 'browse' command * Making namespace, runAsUser & localport flags persistent * Removing namespace, runAsUser & localport flags for browse snapshot because we made those persistent * Adding --show-tree flag for browse snapshot & browse pvc commands * Updating namespace flag usage for better understanding * Removing storage class flag * Adding --show-tree logic in snapshot_inspector.go * Updating mock objects for SnapshotBrowserStepper * Adding --show-tree flag for browse snapshot & browse pvc commands * Removing storage class flag * Adding --show-tree flag for browse snapshot & browse pvc commands * Adding --show-tree logic in snapshot_inspector.go * Passing showTree var as function argument * Making --show-tree a persistent flag * Removing ShowTree dummy condition * Removing duplicate browseSnapshotCmd * Adding --show-tree flag for browse snapshot & browse pvc commands * Making --show-tree a persistent flag * Adding --show-tree flag for browse snapshot & browse pvc commands * Making --show-tree a persistent flag --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
2cf1758a0c
commit
8037d9456d
10 changed files with 205 additions and 17 deletions
|
@ -95,6 +95,8 @@ var (
|
|||
},
|
||||
}
|
||||
|
||||
showTree bool
|
||||
|
||||
browsePvcCmd = &cobra.Command{
|
||||
Use: "pvc [PVC name]",
|
||||
Short: "Browse the contents of a CSI PVC via file browser",
|
||||
|
@ -106,6 +108,7 @@ var (
|
|||
csiCheckVolumeSnapshotClass,
|
||||
csiCheckRunAsUser,
|
||||
browseLocalPort,
|
||||
showTree,
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -120,6 +123,7 @@ var (
|
|||
namespace,
|
||||
csiCheckRunAsUser,
|
||||
browseLocalPort,
|
||||
showTree,
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -195,6 +199,7 @@ func init() {
|
|||
browseCmd.PersistentFlags().StringVarP(&namespace, "namespace", "n", fio.DefaultNS, "The namespace of the resource to browse.")
|
||||
browseCmd.PersistentFlags().Int64VarP(&csiCheckRunAsUser, "runAsUser", "u", 0, "Runs the inspector pod as a user (int)")
|
||||
browseCmd.PersistentFlags().IntVarP(&browseLocalPort, "localport", "l", 8080, "The local port to expose the inspector")
|
||||
browseCmd.PersistentFlags().BoolVarP(&showTree, "show-tree", "t", false, "Prints the contents of given PVC or VolumeSnapshot")
|
||||
|
||||
browseCmd.AddCommand(browsePvcCmd)
|
||||
browsePvcCmd.Flags().StringVarP(&csiCheckVolumeSnapshotClass, "volumesnapshotclass", "v", "", "The name of a VolumeSnapshotClass. (Required)")
|
||||
|
@ -361,6 +366,7 @@ func CsiPvcBrowse(ctx context.Context,
|
|||
volumeSnapshotClass string,
|
||||
runAsUser int64,
|
||||
localPort int,
|
||||
showTree bool,
|
||||
) error {
|
||||
kubecli, err := kubestr.LoadKubeCli()
|
||||
if err != nil {
|
||||
|
@ -382,6 +388,7 @@ func CsiPvcBrowse(ctx context.Context,
|
|||
VolumeSnapshotClass: volumeSnapshotClass,
|
||||
RunAsUser: runAsUser,
|
||||
LocalPort: localPort,
|
||||
ShowTree: showTree,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to run PVC browser (%s)\n", err.Error())
|
||||
|
@ -394,6 +401,7 @@ func CsiSnapshotBrowse(ctx context.Context,
|
|||
namespace string,
|
||||
runAsUser int64,
|
||||
localPort int,
|
||||
showTree bool,
|
||||
) error {
|
||||
kubecli, err := kubestr.LoadKubeCli()
|
||||
if err != nil {
|
||||
|
@ -414,6 +422,7 @@ func CsiSnapshotBrowse(ctx context.Context,
|
|||
Namespace: namespace,
|
||||
RunAsUser: runAsUser,
|
||||
LocalPort: localPort,
|
||||
ShowTree: showTree,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to run Snapshot browser (%s)\n", err.Error())
|
||||
|
|
|
@ -568,3 +568,20 @@ func (p *portforward) PortForwardAPod(req *types.PortForwardAPodRequest) error {
|
|||
func (p *portforward) FetchRestConfig() (*rest.Config, error) {
|
||||
return kube.LoadConfig()
|
||||
}
|
||||
|
||||
//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_kube_executor.go -package=mocks . KubeExecutor
|
||||
type KubeExecutor interface {
|
||||
Exec(ctx context.Context, namespace string, podName string, ContainerName string, command []string) (string, error)
|
||||
}
|
||||
|
||||
type kubeExec struct {
|
||||
kubeCli kubernetes.Interface
|
||||
}
|
||||
|
||||
func (k *kubeExec) Exec(ctx context.Context, namespace string, podName string, ContainerName string, command []string) (string, error) {
|
||||
if k.kubeCli == nil {
|
||||
return "", fmt.Errorf("kubeCli not initialized")
|
||||
}
|
||||
stdout, _, err := kankube.Exec(ctx, k.kubeCli, namespace, podName, ContainerName, command, nil)
|
||||
return stdout, err
|
||||
}
|
||||
|
|
50
pkg/csi/mocks/mock_kube_executor.go
Normal file
50
pkg/csi/mocks/mock_kube_executor.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/kastenhq/kubestr/pkg/csi (interfaces: KubeExecutor)
|
||||
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockKubeExecutor is a mock of KubeExecutor interface.
|
||||
type MockKubeExecutor struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockKubeExecutorMockRecorder
|
||||
}
|
||||
|
||||
// MockKubeExecutorMockRecorder is the mock recorder for MockKubeExecutor.
|
||||
type MockKubeExecutorMockRecorder struct {
|
||||
mock *MockKubeExecutor
|
||||
}
|
||||
|
||||
// NewMockKubeExecutor creates a new mock instance.
|
||||
func NewMockKubeExecutor(ctrl *gomock.Controller) *MockKubeExecutor {
|
||||
mock := &MockKubeExecutor{ctrl: ctrl}
|
||||
mock.recorder = &MockKubeExecutorMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockKubeExecutor) EXPECT() *MockKubeExecutorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Exec mocks base method.
|
||||
func (m *MockKubeExecutor) Exec(arg0 context.Context, arg1, arg2, arg3 string, arg4 []string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Exec", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Exec indicates an expected call of Exec.
|
||||
func (mr *MockKubeExecutorMockRecorder) Exec(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exec", reflect.TypeOf((*MockKubeExecutor)(nil).Exec), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
|
@ -66,6 +66,21 @@ func (mr *MockPVCBrowserStepperMockRecorder) CreateInspectorApplication(arg0, ar
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInspectorApplication", reflect.TypeOf((*MockPVCBrowserStepper)(nil).CreateInspectorApplication), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ExecuteTreeCommand mocks base method.
|
||||
func (m *MockPVCBrowserStepper) ExecuteTreeCommand(arg0 context.Context, arg1 *types.PVCBrowseArgs, arg2 *v10.Pod) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ExecuteTreeCommand", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ExecuteTreeCommand indicates an expected call of ExecuteTreeCommand.
|
||||
func (mr *MockPVCBrowserStepperMockRecorder) ExecuteTreeCommand(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteTreeCommand", reflect.TypeOf((*MockPVCBrowserStepper)(nil).ExecuteTreeCommand), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// PortForwardAPod mocks base method.
|
||||
func (m *MockPVCBrowserStepper) PortForwardAPod(arg0 context.Context, arg1 *v10.Pod, arg2 int) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -66,6 +66,21 @@ func (mr *MockSnapshotBrowserStepperMockRecorder) CreateInspectorApplication(arg
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInspectorApplication", reflect.TypeOf((*MockSnapshotBrowserStepper)(nil).CreateInspectorApplication), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// ExecuteTreeCommand mocks base method.
|
||||
func (m *MockSnapshotBrowserStepper) ExecuteTreeCommand(arg0 context.Context, arg1 *types.SnapshotBrowseArgs, arg2 *v10.Pod) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ExecuteTreeCommand", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ExecuteTreeCommand indicates an expected call of ExecuteTreeCommand.
|
||||
func (mr *MockSnapshotBrowserStepperMockRecorder) ExecuteTreeCommand(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteTreeCommand", reflect.TypeOf((*MockSnapshotBrowserStepper)(nil).ExecuteTreeCommand), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// PortForwardAPod mocks base method.
|
||||
func (m *MockSnapshotBrowserStepper) PortForwardAPod(arg0 context.Context, arg1 *v10.Pod, arg2 int) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -49,11 +49,18 @@ func (r *PVCBrowseRunner) RunPVCBrowse(ctx context.Context, args *types.PVCBrows
|
|||
dynCli: r.DynCli,
|
||||
},
|
||||
portForwardOps: &portforward{},
|
||||
kubeExecutor: &kubeExec{
|
||||
kubeCli: r.KubeCli,
|
||||
},
|
||||
cleanerOps: &cleanse{
|
||||
kubeCli: r.KubeCli,
|
||||
dynCli: r.DynCli,
|
||||
},
|
||||
}
|
||||
if args.ShowTree {
|
||||
fmt.Println("Show Tree works for PVC!")
|
||||
return nil
|
||||
}
|
||||
return r.RunPVCBrowseHelper(ctx, args)
|
||||
}
|
||||
|
||||
|
@ -70,19 +77,29 @@ func (r *PVCBrowseRunner) RunPVCBrowseHelper(ctx context.Context, args *types.PV
|
|||
return errors.Wrap(err, "Failed to validate arguments.")
|
||||
}
|
||||
|
||||
fmt.Println("Taking a snapshot")
|
||||
fmt.Println("Taking a snapshot.")
|
||||
snapName := snapshotPrefix + time.Now().Format("20060102150405")
|
||||
r.snapshot, err = r.browserSteps.SnapshotPVC(ctx, args, snapName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to snapshot PVC.")
|
||||
}
|
||||
|
||||
fmt.Println("Creating the file browser application.")
|
||||
fmt.Println("Creating the browser pod.")
|
||||
r.pod, r.pvc, err = r.browserSteps.CreateInspectorApplication(ctx, args, r.snapshot, sc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to create inspector application.")
|
||||
}
|
||||
|
||||
if args.ShowTree {
|
||||
fmt.Println("Printing the tree structure from root directory.")
|
||||
stdout, err := r.browserSteps.ExecuteTreeCommand(ctx, args, r.pod)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to execute tree command in pod.")
|
||||
}
|
||||
fmt.Printf("\n%s\n\n", stdout)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("Forwarding the port.")
|
||||
err = r.browserSteps.PortForwardAPod(ctx, r.pod, args.LocalPort)
|
||||
if err != nil {
|
||||
|
@ -97,6 +114,7 @@ type PVCBrowserStepper interface {
|
|||
ValidateArgs(ctx context.Context, args *types.PVCBrowseArgs) (*sv1.StorageClass, error)
|
||||
SnapshotPVC(ctx context.Context, args *types.PVCBrowseArgs, snapshotName string) (*snapv1.VolumeSnapshot, error)
|
||||
CreateInspectorApplication(ctx context.Context, args *types.PVCBrowseArgs, snapshot *snapv1.VolumeSnapshot, storageClass *sv1.StorageClass) (*v1.Pod, *v1.PersistentVolumeClaim, error)
|
||||
ExecuteTreeCommand(ctx context.Context, args *types.PVCBrowseArgs, pod *v1.Pod) (string, error)
|
||||
PortForwardAPod(ctx context.Context, pod *v1.Pod, localPort int) error
|
||||
Cleanup(ctx context.Context, pvc *v1.PersistentVolumeClaim, pod *v1.Pod, snapshot *snapv1.VolumeSnapshot)
|
||||
}
|
||||
|
@ -108,6 +126,7 @@ type pvcBrowserSteps struct {
|
|||
snapshotCreateOps SnapshotCreator
|
||||
portForwardOps PortForwarder
|
||||
cleanerOps Cleaner
|
||||
kubeExecutor KubeExecutor
|
||||
SnapshotGroupVersion *metav1.GroupVersionForDiscovery
|
||||
}
|
||||
|
||||
|
@ -194,12 +213,24 @@ func (p *pvcBrowserSteps) CreateInspectorApplication(ctx context.Context, args *
|
|||
Namespace: args.Namespace,
|
||||
RunAsUser: args.RunAsUser,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
|
||||
MountPath: "/pvc-data",
|
||||
}
|
||||
if args.ShowTree {
|
||||
podArgs = &types.CreatePodArgs{
|
||||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: pvc.Name,
|
||||
Namespace: args.Namespace,
|
||||
RunAsUser: args.RunAsUser,
|
||||
ContainerImage: "alpine:3.19",
|
||||
Command: []string{"/bin/sh"},
|
||||
ContainerArgs: []string{"-c", "while true; do sleep 3600; done"},
|
||||
MountPath: "/pvc-data",
|
||||
}
|
||||
}
|
||||
pod, err := p.createAppOps.CreatePod(ctx, podArgs)
|
||||
if err != nil {
|
||||
return nil, pvc, errors.Wrap(err, "Failed to create restored Pod")
|
||||
return nil, pvc, errors.Wrap(err, "Failed to create browse Pod")
|
||||
}
|
||||
if err = p.createAppOps.WaitForPodReady(ctx, args.Namespace, pod.Name); err != nil {
|
||||
return pod, pvc, errors.Wrap(err, "Pod failed to become ready")
|
||||
|
@ -207,6 +238,15 @@ func (p *pvcBrowserSteps) CreateInspectorApplication(ctx context.Context, args *
|
|||
return pod, pvc, nil
|
||||
}
|
||||
|
||||
func (p *pvcBrowserSteps) ExecuteTreeCommand(ctx context.Context, args *types.PVCBrowseArgs, pod *v1.Pod) (string, error) {
|
||||
command := []string{"tree", "/pvc-data"}
|
||||
stdout, err := p.kubeExecutor.Exec(ctx, args.Namespace, pod.Name, pod.Spec.Containers[0].Name, command)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "Error running command:(%v)", command)
|
||||
}
|
||||
return stdout, nil
|
||||
}
|
||||
|
||||
func (p *pvcBrowserSteps) PortForwardAPod(ctx context.Context, pod *v1.Pod, localPort int) error {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
|
|
@ -541,8 +541,8 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForPVC(c *C) {
|
|||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: "pvc1",
|
||||
Namespace: "ns",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
|
||||
MountPath: "/pvc-data",
|
||||
RunAsUser: 100,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
}).Return(&v1.Pod{
|
||||
|
@ -596,8 +596,8 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForPVC(c *C) {
|
|||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: "pvc1",
|
||||
Namespace: "ns",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/pvc-data"},
|
||||
MountPath: "/pvc-data",
|
||||
RunAsUser: 100,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
}).Return(&v1.Pod{
|
||||
|
|
|
@ -44,11 +44,18 @@ func (r *SnapshotBrowseRunner) RunSnapshotBrowse(ctx context.Context, args *type
|
|||
dynCli: r.DynCli,
|
||||
},
|
||||
portForwardOps: &portforward{},
|
||||
kubeExecutor: &kubeExec{
|
||||
kubeCli: r.KubeCli,
|
||||
},
|
||||
cleanerOps: &cleanse{
|
||||
kubeCli: r.KubeCli,
|
||||
dynCli: r.DynCli,
|
||||
},
|
||||
}
|
||||
if args.ShowTree {
|
||||
fmt.Println("Show Tree works for VS!")
|
||||
return nil
|
||||
}
|
||||
return r.RunSnapshotBrowseHelper(ctx, args)
|
||||
}
|
||||
|
||||
|
@ -69,12 +76,22 @@ func (r *SnapshotBrowseRunner) RunSnapshotBrowseHelper(ctx context.Context, args
|
|||
}
|
||||
r.snapshot = vs
|
||||
|
||||
fmt.Println("Creating the file browser application.")
|
||||
fmt.Println("Creating the browser pod.")
|
||||
r.pod, r.pvc, err = r.browserSteps.CreateInspectorApplication(ctx, args, r.snapshot, sc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to create inspector application.")
|
||||
}
|
||||
|
||||
if args.ShowTree {
|
||||
fmt.Println("Printing the tree structure from root directory.")
|
||||
stdout, err := r.browserSteps.ExecuteTreeCommand(ctx, args, r.pod)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to execute tree command in pod.")
|
||||
}
|
||||
fmt.Printf("\n%s\n\n", stdout)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("Forwarding the port.")
|
||||
err = r.browserSteps.PortForwardAPod(ctx, r.pod, args.LocalPort)
|
||||
if err != nil {
|
||||
|
@ -88,6 +105,7 @@ func (r *SnapshotBrowseRunner) RunSnapshotBrowseHelper(ctx context.Context, args
|
|||
type SnapshotBrowserStepper interface {
|
||||
ValidateArgs(ctx context.Context, args *types.SnapshotBrowseArgs) (*snapv1.VolumeSnapshot, *sv1.StorageClass, error)
|
||||
CreateInspectorApplication(ctx context.Context, args *types.SnapshotBrowseArgs, snapshot *snapv1.VolumeSnapshot, storageClass *sv1.StorageClass) (*v1.Pod, *v1.PersistentVolumeClaim, error)
|
||||
ExecuteTreeCommand(ctx context.Context, args *types.SnapshotBrowseArgs, pod *v1.Pod) (string, error)
|
||||
PortForwardAPod(ctx context.Context, pod *v1.Pod, localPort int) error
|
||||
Cleanup(ctx context.Context, pvc *v1.PersistentVolumeClaim, pod *v1.Pod)
|
||||
}
|
||||
|
@ -99,6 +117,7 @@ type snapshotBrowserSteps struct {
|
|||
createAppOps ApplicationCreator
|
||||
portForwardOps PortForwarder
|
||||
cleanerOps Cleaner
|
||||
kubeExecutor KubeExecutor
|
||||
SnapshotGroupVersion *metav1.GroupVersionForDiscovery
|
||||
}
|
||||
|
||||
|
@ -162,12 +181,24 @@ func (s *snapshotBrowserSteps) CreateInspectorApplication(ctx context.Context, a
|
|||
Namespace: args.Namespace,
|
||||
RunAsUser: args.RunAsUser,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
|
||||
MountPath: "/snapshot-data",
|
||||
}
|
||||
if args.ShowTree {
|
||||
podArgs = &types.CreatePodArgs{
|
||||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: pvc.Name,
|
||||
Namespace: args.Namespace,
|
||||
RunAsUser: args.RunAsUser,
|
||||
ContainerImage: "alpine:3.19",
|
||||
Command: []string{"/bin/sh"},
|
||||
ContainerArgs: []string{"-c", "while true; do sleep 3600; done"},
|
||||
MountPath: "/snapshot-data",
|
||||
}
|
||||
}
|
||||
pod, err := s.createAppOps.CreatePod(ctx, podArgs)
|
||||
if err != nil {
|
||||
return nil, pvc, errors.Wrap(err, "Failed to create restored Pod")
|
||||
return nil, pvc, errors.Wrap(err, "Failed to create browse Pod")
|
||||
}
|
||||
if err = s.createAppOps.WaitForPodReady(ctx, args.Namespace, pod.Name); err != nil {
|
||||
return pod, pvc, errors.Wrap(err, "Pod failed to become ready")
|
||||
|
@ -175,6 +206,15 @@ func (s *snapshotBrowserSteps) CreateInspectorApplication(ctx context.Context, a
|
|||
return pod, pvc, nil
|
||||
}
|
||||
|
||||
func (s *snapshotBrowserSteps) ExecuteTreeCommand(ctx context.Context, args *types.SnapshotBrowseArgs, pod *v1.Pod) (string, error) {
|
||||
command := []string{"tree", "/snapshot-data"}
|
||||
stdout, err := s.kubeExecutor.Exec(ctx, args.Namespace, pod.Name, pod.Spec.Containers[0].Name, command)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "Error running command:(%v)", command)
|
||||
}
|
||||
return stdout, nil
|
||||
}
|
||||
|
||||
func (s *snapshotBrowserSteps) PortForwardAPod(ctx context.Context, pod *v1.Pod, localPort int) error {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
|
|
@ -345,8 +345,8 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForSnapshot(c *C) {
|
|||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: "pvc",
|
||||
Namespace: "ns",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
|
||||
MountPath: "/snapshot-data",
|
||||
RunAsUser: 100,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
}).Return(&v1.Pod{
|
||||
|
@ -400,8 +400,8 @@ func (s *CSITestSuite) TestCreateInspectorApplicationForSnapshot(c *C) {
|
|||
GenerateName: clonedPodGenerateName,
|
||||
PVCName: "pvc",
|
||||
Namespace: "ns",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/data"},
|
||||
MountPath: "/data",
|
||||
ContainerArgs: []string{"--noauth", "-r", "/snapshot-data"},
|
||||
MountPath: "/snapshot-data",
|
||||
RunAsUser: 100,
|
||||
ContainerImage: "filebrowser/filebrowser:v2",
|
||||
}).Return(&v1.Pod{
|
||||
|
|
|
@ -125,6 +125,7 @@ type PVCBrowseArgs struct {
|
|||
VolumeSnapshotClass string
|
||||
RunAsUser int64
|
||||
LocalPort int
|
||||
ShowTree bool
|
||||
}
|
||||
|
||||
func (p *PVCBrowseArgs) Validate() error {
|
||||
|
@ -139,6 +140,7 @@ type SnapshotBrowseArgs struct {
|
|||
Namespace string
|
||||
RunAsUser int64
|
||||
LocalPort int
|
||||
ShowTree bool
|
||||
}
|
||||
|
||||
func (p *SnapshotBrowseArgs) Validate() error {
|
||||
|
|
Loading…
Reference in a new issue