Skip to content

Commit

Permalink
Merge branch 'master' into orange/saima/support-snapshot-annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
saima-s authored Aug 5, 2024
2 parents 4fd000f + 9a28659 commit 19faa34
Show file tree
Hide file tree
Showing 15 changed files with 1,542 additions and 38 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ jobs:
# This action can be useful if you want to add emulation
# support with QEMU to be able to build against more platforms.
- name: Set up QEMU
uses: docker/setup-qemu-action@5927c834f5b4fdf503fca6f4c7eccda82949e1ee # v3.1.0
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0

# This action will create and boot a builder using
# by default the docker-container builder driver.
# Recommended for build multi-platform images, export cache, etc.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1

- name: Log into ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand All @@ -59,7 +59,7 @@ jobs:
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@1ca370b3a9802c92e886402e0dd88098a2533b12 # v6.4.1
uses: docker/build-push-action@5176d81f87c23d6fc96624dfdbcd9f3830bbe445 # v6.5.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ossf-scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ jobs:
persist-credentials: false
-
name: "Run analysis"
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
publish_results: true
-
# Upload the results to GitHub's code scanning dashboard.
name: "Upload to results to dashboard"
uses: github/codeql-action/upload-sarif@2d790406f505036ef40ecba973cc774a50395aac # v3.25.13
uses: github/codeql-action/upload-sarif@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
with:
sarif_file: results.sarif
-
name: "Upload analysis results as 'Job Artifact'"
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5
with:
name: SARIF file
path: results.sarif
Expand Down
94 changes: 83 additions & 11 deletions cmd/rootCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,22 @@ var (
},
}

pvcBrowseLocalPort int
pvcBrowseCmd = &cobra.Command{
Use: "browse [PVC name]",
browseLocalPort int
browseCmd = &cobra.Command{
Use: "browse",
Short: "Browse the contents of PVC or VolumeSnapshot",
Long: "Browse the contents of a CSI provisioned PVC or a CSI provisioned VolumeSnapshot.",
Deprecated: "use 'browse pvc' instead",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return browsePvcCmd.RunE(cmd, args)
},
}

showTree bool

browsePvcCmd = &cobra.Command{
Use: "pvc [PVC name]",
Short: "Browse the contents of a CSI PVC via file browser",
Long: "Browse the contents of a CSI provisioned PVC by cloning the volume and mounting it with a file browser.",
Args: cobra.ExactArgs(1),
Expand All @@ -94,7 +107,23 @@ var (
namespace,
csiCheckVolumeSnapshotClass,
csiCheckRunAsUser,
pvcBrowseLocalPort,
browseLocalPort,
showTree,
)
},
}

browseSnapshotCmd = &cobra.Command{
Use: "snapshot [Snapshot name]",
Short: "Browse the contents of a CSI VolumeSnapshot via file browser",
Long: "Browse the contents of a CSI provisioned VolumeSnapshot by cloning the volume and mounting it with a file browser.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return CsiSnapshotBrowse(context.Background(), args[0],
namespace,
csiCheckRunAsUser,
browseLocalPort,
showTree,
)
},
}
Expand Down Expand Up @@ -164,15 +193,22 @@ func init() {
csiCheckCmd.Flags().Int64VarP(&csiCheckRunAsUser, "runAsUser", "u", 0, "Runs the CSI check pod with the specified user ID (int)")
csiCheckCmd.Flags().BoolVarP(&csiCheckSkipCFSCheck, "skipCFScheck", "k", false, "Use this flag to skip validating the ability to clone a snapshot.")

rootCmd.AddCommand(pvcBrowseCmd)
pvcBrowseCmd.Flags().StringVarP(&csiCheckVolumeSnapshotClass, "volumesnapshotclass", "v", "", "The name of a VolumeSnapshotClass. (Required)")
_ = pvcBrowseCmd.MarkFlagRequired("volumesnapshotclass")
pvcBrowseCmd.Flags().StringVarP(&namespace, "namespace", "n", fio.DefaultNS, "The namespace of the PersistentVolumeClaim.")
pvcBrowseCmd.Flags().Int64VarP(&csiCheckRunAsUser, "runAsUser", "u", 0, "Runs the inspector pod as a user (int)")
pvcBrowseCmd.Flags().IntVarP(&pvcBrowseLocalPort, "localport", "l", 8080, "The local port to expose the inspector")
rootCmd.AddCommand(browseCmd)
browseCmd.Flags().StringVarP(&csiCheckVolumeSnapshotClass, "volumesnapshotclass", "v", "", "The name of a VolumeSnapshotClass. (Required)")
_ = browseCmd.MarkFlagRequired("volumesnapshotclass")
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)")
_ = browsePvcCmd.MarkFlagRequired("volumesnapshotclass")

browseCmd.AddCommand(browseSnapshotCmd)

rootCmd.AddCommand(blockMountCmd)
blockMountCmd.Flags().StringVarP(&storageClass, "storageclass", "s", "", "The name of a Storageclass. (Required)")
blockMountCmd.Flags().StringVarP(&storageClass, "storageclass", "s", "", "The name of a StorageClass. (Required)")
_ = blockMountCmd.MarkFlagRequired("storageclass")
blockMountCmd.Flags().StringVarP(&namespace, "namespace", "n", fio.DefaultNS, "The namespace used to run the check.")
blockMountCmd.Flags().StringVarP(&containerImage, "image", "i", "", "The container image used to create a pod.")
Expand Down Expand Up @@ -330,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 @@ -351,13 +388,48 @@ 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())
}
return err
}

func CsiSnapshotBrowse(ctx context.Context,
snapshotName string,
namespace string,
runAsUser int64,
localPort int,
showTree bool,
) error {
kubecli, err := kubestr.LoadKubeCli()
if err != nil {
fmt.Printf("Failed to load kubeCli (%s)", err.Error())
return err
}
dyncli, err := kubestr.LoadDynCli()
if err != nil {
fmt.Printf("Failed to load dynCli (%s)", err.Error())
return err
}
browseRunner := &csi.SnapshotBrowseRunner{
KubeCli: kubecli,
DynCli: dyncli,
}
err = browseRunner.RunSnapshotBrowse(ctx, &csitypes.SnapshotBrowseArgs{
SnapshotName: snapshotName,
Namespace: namespace,
RunAsUser: runAsUser,
LocalPort: localPort,
ShowTree: showTree,
})
if err != nil {
fmt.Printf("Failed to run Snapshot browser (%s)\n", err.Error())
}
return err
}

func BlockMountCheck(ctx context.Context, output, outfile string, cleanupOnly bool, checkerArgs block.BlockMountCheckerArgs) error {
kubecli, err := kubestr.LoadKubeCli()
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions pkg/csi/csi_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package csi
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"log"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -44,6 +46,7 @@ type ArgumentValidator interface {
//Rename
ValidatePVC(ctx context.Context, pvcName, namespace string) (*v1.PersistentVolumeClaim, error)
FetchPV(ctx context.Context, pvName string) (*v1.PersistentVolume, error)
ValidateVolumeSnapshot(ctx context.Context, snapshotName, namespace string, groupVersion *metav1.GroupVersionForDiscovery) (*snapv1.VolumeSnapshot, error)
ValidateNamespace(ctx context.Context, namespace string) error
ValidateStorageClass(ctx context.Context, storageClass string) (*sv1.StorageClass, error)
ValidateVolumeSnapshotClass(ctx context.Context, volumeSnapshotClass string, groupVersion *metav1.GroupVersionForDiscovery) (*unstructured.Unstructured, error)
Expand All @@ -68,6 +71,17 @@ func (o *validateOperations) ValidatePVC(ctx context.Context, pvcName, namespace
return o.kubeCli.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, pvcName, metav1.GetOptions{})
}

func (o *validateOperations) ValidateVolumeSnapshot(ctx context.Context, snapshotName, namespace string, groupVersion *metav1.GroupVersionForDiscovery) (*snapv1.VolumeSnapshot, error) {
VolSnapGVR := schema.GroupVersionResource{Group: snapv1.GroupName, Version: groupVersion.Version, Resource: common.VolumeSnapshotResourcePlural}
uVS, err := o.dynCli.Resource(VolSnapGVR).Namespace(namespace).Get(ctx, snapshotName, metav1.GetOptions{})
if err != nil {
log.Fatalf("Failed to get VolumeSnapshot: %v", err)
}
volumeSnapshot := &snapv1.VolumeSnapshot{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(uVS.UnstructuredContent(), volumeSnapshot)
return volumeSnapshot, err
}

func (o *validateOperations) FetchPV(ctx context.Context, pvName string) (*v1.PersistentVolume, error) {
if o.kubeCli == nil {
return nil, fmt.Errorf("kubeCli not initialized")
Expand Down Expand Up @@ -317,6 +331,41 @@ func (c *applicationCreate) getErrorFromEvents(ctx context.Context, namespace, n
return nil
}

//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_snapshot_fetcher.go -package=mocks . SnapshotFetcher
type SnapshotFetcher interface {
NewSnapshotter() (kansnapshot.Snapshotter, error)
GetVolumeSnapshot(ctx context.Context, snapshotter kansnapshot.Snapshotter, args *types.FetchSnapshotArgs) (*snapv1.VolumeSnapshot, error)
}

type snapshotFetch struct {
kubeCli kubernetes.Interface
dynCli dynamic.Interface
}

func (f *snapshotFetch) NewSnapshotter() (kansnapshot.Snapshotter, error) {
if f.kubeCli == nil {
return nil, fmt.Errorf("kubeCli not initialized")
}
if f.dynCli == nil {
return nil, fmt.Errorf("dynCli not initialized")
}
return kansnapshot.NewSnapshotter(f.kubeCli, f.dynCli)
}

func (f *snapshotFetch) GetVolumeSnapshot(ctx context.Context, snapshotter kansnapshot.Snapshotter, args *types.FetchSnapshotArgs) (*snapv1.VolumeSnapshot, error) {
if snapshotter == nil || args == nil {
return nil, fmt.Errorf("snapshotter or args are empty")
}
if err := args.Validate(); err != nil {
return nil, err
}
snap, err := snapshotter.Get(ctx, args.SnapshotName, args.Namespace)
if err != nil {
return nil, errors.Wrapf(err, "Failed to get CSI snapshot (%s) in Namespace (%s)", args.SnapshotName, args.Namespace)
}
return snap, nil
}

//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_snapshot_creator.go -package=mocks . SnapshotCreator
type SnapshotCreator interface {
NewSnapshotter() (kansnapshot.Snapshotter, error)
Expand Down Expand Up @@ -527,3 +576,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
}
36 changes: 26 additions & 10 deletions pkg/csi/mocks/mock_argument_validator.go

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

Loading

0 comments on commit 19faa34

Please sign in to comment.