Skip to content

Commit

Permalink
Adding --show-tree flag to both "./kubestr browse pvc" & "./kubestr b…
Browse files Browse the repository at this point in the history
…rowse 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](github/codeql-action@4fa2a79...2d79040)

---
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] <[email protected]>
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](docker/build-push-action@1a16264...1ca370b)

---
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] <[email protected]>
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] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
shlokc9 and dependabot[bot] authored Aug 2, 2024
1 parent 2cf1758 commit 8037d94
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 17 deletions.
9 changes: 9 additions & 0 deletions cmd/rootCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -106,6 +108,7 @@ var (
csiCheckVolumeSnapshotClass,
csiCheckRunAsUser,
browseLocalPort,
showTree,
)
},
}
Expand All @@ -120,6 +123,7 @@ var (
namespace,
csiCheckRunAsUser,
browseLocalPort,
showTree,
)
},
}
Expand Down Expand Up @@ -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)")
Expand Down Expand Up @@ -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 {
Expand All @@ -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())
Expand All @@ -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 {
Expand All @@ -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())
Expand Down
17 changes: 17 additions & 0 deletions pkg/csi/csi_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 50 additions & 0 deletions pkg/csi/mocks/mock_kube_executor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pkg/csi/mocks/mock_pvc_browser_stepper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pkg/csi/mocks/mock_snapshot_browser_stepper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 45 additions & 5 deletions pkg/csi/pvc_inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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 {
Expand All @@ -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)
}
Expand All @@ -108,6 +126,7 @@ type pvcBrowserSteps struct {
snapshotCreateOps SnapshotCreator
portForwardOps PortForwarder
cleanerOps Cleaner
kubeExecutor KubeExecutor
SnapshotGroupVersion *metav1.GroupVersionForDiscovery
}

Expand Down Expand Up @@ -194,19 +213,40 @@ 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")
}
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)
Expand Down
8 changes: 4 additions & 4 deletions pkg/csi/pvc_inspector_steps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand Down
Loading

0 comments on commit 8037d94

Please sign in to comment.