├── .github ├── CODEOWNERS ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── common-workflows.yaml │ ├── create-tag-release.yaml │ ├── go-version.yaml │ ├── image-version-update.yaml │ ├── license-checker.yaml │ ├── release-image.yaml │ ├── update-libraries-to-commits.yaml │ └── update-libraries.yaml ├── .gitignore ├── .trivyignore ├── Dockerfile ├── Gopkg.toml ├── LICENSE ├── Makefile ├── README.md ├── common ├── constants │ ├── consts.go │ └── envvars.go ├── k8sutils │ ├── k8sutils.go │ └── k8sutils_test.go └── utils │ ├── fromcontext │ ├── from-context.go │ └── from-context_test.go │ ├── identifiers │ ├── fqdn.go │ ├── fqdn_test.go │ ├── node.go │ ├── node_test.go │ ├── snapshot.go │ ├── snapshot_test.go │ ├── uuid.go │ ├── uuid_test.go │ ├── volume.go │ └── volume_test.go │ ├── logging │ ├── logging.go │ └── logging_test.go │ ├── powerscale-fs │ ├── powerscale-fs.go │ └── powerscale-fs_test.go │ └── string-utils │ ├── string-utils.go │ └── string-utils_test.go ├── core ├── .gitignore ├── core.go ├── semver.tpl └── semver │ ├── semver.go │ └── semver_test.go ├── csi-utils ├── csiutils.go └── csiutils_test.go ├── dell-csi-helm-installer ├── .gitignore ├── README.md ├── common.sh ├── csi-install.sh ├── csi-offline-bundle.md ├── csi-offline-bundle.sh ├── csi-uninstall.sh ├── verify-csi-isilon.sh └── verify.sh ├── docker.mk ├── go.mod ├── go.sum ├── licenses └── LICENSE ├── main.go ├── main_test.go ├── overrides.mk ├── provider ├── provider.go └── provider_test.go ├── samples ├── persistentvolumeclaim │ ├── pvc-from-pvc.yaml │ ├── pvc-from-snapshot.yaml │ └── pvc.yaml ├── pod │ ├── inline-volume.yaml │ └── nginx.yaml ├── secret │ ├── empty-secret.yaml │ ├── karavi-authorization-config.json │ └── secret.yaml ├── storageclass │ ├── isilon-replication.yaml │ └── isilon.yaml ├── volumesnapshot │ └── snapshot-of-test-pvc.yaml └── volumesnapshotclass │ └── isilon-volumesnapshotclass-v1.yaml ├── service ├── controller.go ├── controllerNodeToArrayConnectivity.go ├── controllerNodeToArrayConnectivity_test.go ├── controller_test.go ├── csi_extension_server.go ├── features │ ├── controller_create_delete_snapshot.feature │ ├── controller_create_delete_volume.feature │ ├── controller_expand_volume.feature │ ├── csi_extension.feature │ ├── isiService.feature │ ├── node_publish_unpublish.feature │ ├── replication.feature │ └── service.feature ├── identity.go ├── interceptor │ ├── interceptor.go │ └── interceptor_test.go ├── isiService.go ├── isiService_test.go ├── mock │ ├── cluster │ │ └── get_cluster_config.txt │ ├── export │ │ ├── create_export_557.txt │ │ ├── export_not_found_by_id.txt │ │ ├── get_all_exports_including_volume2.txt │ │ ├── get_export_557.txt │ │ ├── get_export_not_found.txt │ │ ├── get_export_snapVol3.txt │ │ ├── get_exports_snapVol2.txt │ │ ├── get_exports_with_invalid_resume.txt │ │ ├── get_exports_with_limit.txt │ │ └── get_exports_with_resume.txt │ ├── jobs │ │ ├── created.json │ │ ├── empty.json │ │ └── running.json │ ├── k8s │ │ ├── admin.conf │ │ └── fakeNodeCreator.go │ ├── loglevel │ │ ├── logBackup.yaml │ │ ├── logConfig.yaml │ │ ├── logConfigError.yaml │ │ └── logLevelInfo.yaml │ ├── policy │ │ ├── empty.txt │ │ ├── get_policies.txt │ │ ├── get_policies2.txt │ │ ├── get_policies_sync.txt │ │ ├── get_target_policies.txt │ │ ├── get_target_policies2.txt │ │ └── tp_failed.txt │ ├── quota │ │ ├── create_quota.txt │ │ ├── get_quota_by_id.txt │ │ ├── get_quota_by_id_4gb.txt │ │ ├── get_quota_by_id_8gb.txt │ │ ├── get_quota_license.txt │ │ ├── invalid_quota.txt │ │ └── quota_not_found.txt │ ├── report │ │ ├── get_report_by_policy.txt │ │ └── get_report_no_error.txt │ ├── secret │ │ └── secret.yaml │ ├── snapshot │ │ ├── create_snapshot.txt │ │ ├── get_existent_compatible_snapshot.txt │ │ ├── get_existent_snapshot_2.txt │ │ ├── get_existent_snapshot_4.txt │ │ ├── get_non_existent_snapshot.txt │ │ ├── get_snapshot_size.txt │ │ └── get_zone_by_name.txt │ ├── statistics │ │ └── IO_not_inprogress.txt │ └── volume │ │ ├── get_non_existent_volume.txt │ │ ├── get_volume2_without_metadata.txt │ │ └── get_volume_size.txt ├── mount.go ├── mount_test.go ├── node.go ├── nodeConnectivityChecker.go ├── nodeConnectivityChecker_test.go ├── node_test.go ├── replication.go ├── replication_test.go ├── service.go ├── service_test.go ├── step_defs_test.go ├── step_handlers_test.go └── test │ └── tmp │ ├── datafile │ └── datafile2 └── test ├── helm ├── .gitignore ├── 10vols │ ├── Chart.yaml │ └── templates │ │ ├── pvc.yaml │ │ └── test.yaml ├── 1vol │ ├── Chart.yaml │ └── templates │ │ ├── createSnapshot.yaml │ │ ├── createVolumeFromSnapshot.yaml │ │ ├── createVolumeFromVolume.yaml │ │ ├── pvc0.yaml │ │ ├── test_pod.yaml │ │ └── test_statefulset.yaml ├── 2vols+restore │ ├── Chart.yaml │ └── templates │ │ ├── createFromSnap.yaml │ │ ├── pvc0.yaml │ │ ├── pvc1.yaml │ │ └── test.yaml ├── 2vols │ ├── Chart.yaml │ └── templates │ │ ├── pvc0.yaml │ │ ├── pvc1.yaml │ │ └── test.yaml ├── 7vols │ ├── Chart.yaml │ └── templates │ │ ├── pvc.yaml │ │ └── test.yaml ├── README.md ├── deletepvcs.sh ├── get.volume.ids ├── logit.sh ├── snap1.yaml ├── snap2.yaml ├── snaprestoretest.sh ├── snaptest.sh ├── starttest.sh └── stoptest.sh ├── ingestion ├── README.md ├── ingestion_test.sh └── sample │ ├── isilonstaticpv.yaml │ └── isilonstaticpvc.yaml ├── integration ├── README.md ├── config ├── env_Custom_Topology_Enabled.sh ├── env_Quota_Enabled.sh ├── env_Quota_notEnabled.sh ├── env_nodeIP1.sh ├── env_nodeIP2.sh ├── features │ ├── integration.feature │ ├── main_integration.feature │ └── mock_different_nodeIPs.feature ├── integration_test.go ├── kubevirt │ ├── README.md │ ├── isilon-sc.yaml │ └── manifest.yaml ├── run.sh └── step_defs_test.go └── scale_longevity ├── README.md ├── env.sh ├── longevity.sh ├── scaletest.sh └── volumes ├── Chart.yaml ├── templates └── test.yaml └── values.yaml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS 2 | # 3 | # documentation for this file can be found at: 4 | # https://help.github.com/en/articles/about-code-owners 5 | 6 | # These are the default owners for the code and will 7 | # be requested for review when someone opens a pull request. 8 | # order is alphabetical for easier maintenance. 9 | # 10 | # Aaron Tye (atye) 11 | # Alik Saring (alikdell) 12 | # Bahubali Jain (bpjain2004) 13 | # Chiman Jain (chimanjain) 14 | # Christian Coffield (ChristianAtDell) 15 | # Don Khan (donatwork) 16 | # Harish H (HarishH-DELL) 17 | # Meghana GM (meggm) 18 | # Nitesh Rewatkar (nitesh3108) 19 | # Prasanna Muthukumaraswamy (prablr79) 20 | # Rajkumar Palani (rajkumar-palani) 21 | # Sakshi Makkar (Sakshi-dell) 22 | # Santhosh Lakshmanan (santhoshatdell) 23 | # Shayna Finocchiaro (shaynafinocchiaro) 24 | # Sharmila Ramamoorthy (sharmilarama) 25 | # Shefali Malhotra (shefali-malhotra) 26 | 27 | # for all files: 28 | * @atye @alikdell @bpjain2004 @chimanjain @ChristianAtDell @donatwork @HarishH-DELL @meggm @nitesh3108 @prablr79 @rajkumar-palani @Sakshi-dell @santhoshatdell @shaynafinocchiaro @sharmilarama @shefali-malhotra 29 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # To get started with Dependabot version updates, you'll need to specify which 3 | # package ecosystems to update and where the package manifests are located. 4 | # Please see the documentation for all configuration options: 5 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 6 | 7 | version: 2 8 | updates: 9 | # Schedule for go module updates 10 | - package-ecosystem: "gomod" 11 | directory: "/" 12 | schedule: 13 | interval: "weekly" 14 | day: "sunday" 15 | time: "18:00" 16 | allow: 17 | # Allow direct updates for packages 18 | - dependency-type: direct 19 | ignore: 20 | - dependency-name: "*" 21 | update-types: 22 | - version-update:semver-patch 23 | # a group of dependencies will be updated together in one pull request 24 | groups: 25 | golang: 26 | # group all semantic versioning levels together in one pull request 27 | update-types: 28 | - major 29 | - minor 30 | patterns: 31 | - "*" 32 | 33 | # github actions 34 | - package-ecosystem: "github-actions" 35 | directory: "/" 36 | schedule: 37 | # Check for updates to GitHub Actions every week 38 | interval: "weekly" 39 | day: "saturday" 40 | groups: 41 | github-actions: 42 | patterns: 43 | - "*" 44 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | A few sentences describing the overall goals of the pull request's commits. 3 | 4 | # GitHub Issues 5 | List the GitHub issues impacted by this PR: 6 | 7 | | GitHub Issue # | 8 | | -------------- | 9 | | | 10 | 11 | # Checklist: 12 | 13 | - [ ] I have performed a self-review of my own code to ensure there are no formatting, vetting, linting, or security issues 14 | - [ ] I have verified that new and existing unit tests pass locally with my changes 15 | - [ ] I have not allowed coverage numbers to degenerate 16 | - [ ] I have maintained at least 90% code coverage 17 | - [ ] I have commented my code, particularly in hard-to-understand areas 18 | - [ ] I have made corresponding changes to the documentation 19 | - [ ] I have added tests that prove my fix is effective or that my feature works 20 | - [ ] Backward compatibility is not broken 21 | 22 | # How Has This Been Tested? 23 | Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration 24 | 25 | - [ ] Test A 26 | - [ ] Test B 27 | -------------------------------------------------------------------------------- /.github/workflows/common-workflows.yaml: -------------------------------------------------------------------------------- 1 | name: Common Workflows 2 | on: # yamllint disable-line rule:truthy 3 | push: 4 | branches: [main] 5 | pull_request: 6 | branches: ["**"] 7 | 8 | jobs: 9 | 10 | # golang static analysis checks 11 | go-static-analysis: 12 | uses: dell/common-github-actions/.github/workflows/go-static-analysis.yaml@main 13 | name: Golang Validation 14 | 15 | common: 16 | name: Quality Checks 17 | uses: dell/common-github-actions/.github/workflows/go-common.yml@main 18 | -------------------------------------------------------------------------------- /.github/workflows/create-tag-release.yaml: -------------------------------------------------------------------------------- 1 | name: Create Tag and Release 2 | # Invocable as a reusable workflow 3 | # Can be manually triggered 4 | on: # yamllint disable-line rule:truthy 5 | workflow_call: 6 | workflow_dispatch: 7 | inputs: 8 | option: 9 | description: 'Select version to release' 10 | required: true 11 | type: choice 12 | default: 'minor' 13 | options: 14 | - major 15 | - minor 16 | - patch 17 | - n-1/n-2 patch (Provide input in the below box) 18 | version: 19 | description: "Patch version to release. example: 2.1.x (Use this only if n-1/n-2 patch is selected)" 20 | required: false 21 | type: string 22 | repository_dispatch: 23 | types: [auto-release-workflow] 24 | 25 | jobs: 26 | process-inputs: 27 | name: Process Inputs 28 | runs-on: ubuntu-latest 29 | outputs: 30 | processedVersion: ${{ steps.set-version.outputs.versionEnv }} 31 | steps: 32 | - name: Process input 33 | id: set-version 34 | shell: bash 35 | run: | 36 | echo "Triggered by: ${{ github.event_name }}" 37 | if [[ "${{ github.event_name }}" == "repository_dispatch" ]]; then 38 | echo "versionEnv=minor" >> $GITHUB_OUTPUT 39 | exit 0 40 | fi 41 | if [[ "${{ github.event.inputs.version }}" != "" && "${{ github.event.inputs.option }}" == "n-1/n-2 patch (Provide input in the below box)" ]]; then 42 | echo "versionEnv=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT 43 | exit 0 44 | fi 45 | if [[ "${{ github.event.inputs.option }}" != "n-1/n-2 patch (Provide input in the below box)" ]]; then 46 | echo "versionEnv=${{ github.event.inputs.option }}" >> $GITHUB_OUTPUT 47 | exit 0 48 | fi 49 | echo "versionEnv=minor" >> $GITHUB_OUTPUT 50 | 51 | csm-release: 52 | needs: process-inputs 53 | uses: dell/common-github-actions/.github/workflows/create-tag-release.yaml@main 54 | name: Create Tag and Release 55 | with: 56 | version: ${{ needs.process-inputs.outputs.processedVersion }} 57 | images: 'csi-isilon' 58 | secrets: inherit 59 | 60 | next-steps: 61 | name: 📌 Next Steps for Release Process 62 | runs-on: ubuntu-latest 63 | needs: csm-release 64 | steps: 65 | - name: Share next steps with user 66 | run: | 67 | echo "✅ Tag and release completed." 68 | echo "➡️ Please manually trigger the Jenkins image build job: CSM-Images-Build-Nightly." 69 | echo "🚀 Once the Jenkins image build job is successful, trigger the Release Image workflow from GitHub Actions." 70 | -------------------------------------------------------------------------------- /.github/workflows/go-version.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Reusable workflow to perform go version update on Golang based projects 10 | name: Go Version Update 11 | 12 | on: # yamllint disable-line rule:truthy 13 | workflow_dispatch: 14 | repository_dispatch: 15 | types: [go-update-workflow] 16 | 17 | jobs: 18 | # go version update 19 | go-version-update: 20 | uses: dell/common-github-actions/.github/workflows/go-version-workflow.yaml@main 21 | name: Go Version Update 22 | secrets: inherit 23 | -------------------------------------------------------------------------------- /.github/workflows/image-version-update.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Dell Inc., or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Reusable workflow to perform image version update on Golang based projects 10 | name: Image Version Update 11 | 12 | on: # yamllint disable-line rule:truthy 13 | workflow_dispatch: 14 | inputs: 15 | version: 16 | description: "Version to release (major, minor, patch) Ex: minor" 17 | required: true 18 | repository_dispatch: 19 | types: [image-update-workflow] 20 | 21 | jobs: 22 | # image version update 23 | image-version-update: 24 | uses: dell/common-github-actions/.github/workflows/image-version-workflow.yaml@main 25 | with: 26 | version: "${{ github.event.inputs.version || 'minor' }}" 27 | secrets: inherit 28 | -------------------------------------------------------------------------------- /.github/workflows/license-checker.yaml: -------------------------------------------------------------------------------- 1 | name: Weekly License Header Check 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * 1' # Runs every Monday at 00:00 UTC 6 | workflow_dispatch: 7 | jobs: 8 | license-check: 9 | name: Run License Header Checker 10 | uses: dell/common-github-actions/.github/workflows/license-checker.yaml@main 11 | secrets: inherit 12 | -------------------------------------------------------------------------------- /.github/workflows/release-image.yaml: -------------------------------------------------------------------------------- 1 | name: Release CSI-Powerscale Image 2 | # Invocable as a reusable workflow 3 | # Can be manually triggered 4 | on: # yamllint disable-line rule:truthy 5 | workflow_call: 6 | workflow_dispatch: 7 | inputs: 8 | option: 9 | description: 'Select version to release' 10 | required: true 11 | type: choice 12 | default: 'minor' 13 | options: 14 | - major 15 | - minor 16 | - patch 17 | - n-1/n-2 patch (Provide input in the below box) 18 | version: 19 | description: "Patch version to release. example: 2.1.x (Use this only if n-1/n-2 patch is selected)" 20 | required: false 21 | type: string 22 | repository_dispatch: 23 | types: [auto-release-workflow] 24 | jobs: 25 | process-inputs: 26 | name: Process Inputs 27 | runs-on: ubuntu-latest 28 | outputs: 29 | processedVersion: ${{ steps.set-version.outputs.versionEnv }} 30 | steps: 31 | - name: Process input 32 | id: set-version 33 | shell: bash 34 | run: | 35 | echo "Triggered by: ${{ github.event_name }}" 36 | if [[ "${{ github.event_name }}" == "repository_dispatch" ]]; then 37 | echo "versionEnv=minor" >> $GITHUB_OUTPUT 38 | exit 0 39 | fi 40 | if [[ "${{ github.event.inputs.version }}" != "" && "${{ github.event.inputs.option }}" == "n-1/n-2 patch (Provide input in the below box)" ]]; then 41 | # if both version and option are provided, then version takes precedence i.e. patch release for n-1/n-2 42 | echo "versionEnv=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT 43 | exit 0 44 | fi 45 | if [[ "${{ github.event.inputs.option }}" != "n-1/n-2 patch (Provide input in the below box)" ]]; then 46 | # if only option is provided, then option takes precedence i.e. minor, major or patch release 47 | echo "versionEnv=${{ github.event.inputs.option }}" >> $GITHUB_OUTPUT 48 | exit 0 49 | fi 50 | # if neither option nor version is provided, then minor release is taken by default (Auto-release) 51 | echo "versionEnv=minor" >> $GITHUB_OUTPUT 52 | csm-release: 53 | needs: [process-inputs] 54 | uses: dell/common-github-actions/.github/workflows/release-image.yaml@main 55 | name: Release Image 56 | with: 57 | version: ${{ needs.process-inputs.outputs.processedVersion }} 58 | images: 'csi-isilon' 59 | secrets: inherit 60 | -------------------------------------------------------------------------------- /.github/workflows/update-libraries-to-commits.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Dell Inc., or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Reusable workflow to perform updates of Dell client libraries to latest commits 10 | name: Dell Libraries Commit Update 11 | on: # yamllint disable-line rule:truthy 12 | workflow_dispatch: 13 | repository_dispatch: 14 | types: [latest-commits-libraries] 15 | 16 | jobs: 17 | package-update: 18 | uses: dell/common-github-actions/.github/workflows/update-libraries-to-commits.yml@main 19 | name: Dell Libraries Update 20 | secrets: inherit 21 | -------------------------------------------------------------------------------- /.github/workflows/update-libraries.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Dell Inc., or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Reusable workflow to perform updates of Dell client libraries 10 | name: Dell Libraries Release Update 11 | on: # yamllint disable-line rule:truthy 12 | workflow_dispatch: 13 | repository_dispatch: 14 | types: [latest-released-libraries] 15 | 16 | jobs: 17 | package-update: 18 | uses: dell/common-github-actions/.github/workflows/update-libraries.yml@main 19 | name: Dell Libraries Update 20 | secrets: inherit 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | *.html 14 | 15 | # reports 16 | *.csv 17 | 18 | *.swp 19 | helm/myvalues.yaml 20 | semver.mk 21 | goisilon 22 | gocsi 23 | .idea 24 | csm-common.mk 25 | go-code-tester 26 | -------------------------------------------------------------------------------- /.trivyignore: -------------------------------------------------------------------------------- 1 | CVE-2019-1010022 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright © 2021-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License 12 | 13 | # some arguments that must be supplied 14 | ARG GOPROXY 15 | ARG GOIMAGE 16 | ARG BASEIMAGE 17 | 18 | # Stage to build the driver 19 | FROM $GOIMAGE as builder 20 | ARG GOPROXY 21 | RUN mkdir -p /go/src 22 | COPY ./ /go/src/ 23 | WORKDIR /go/src/ 24 | RUN CGO_ENABLED=0 \ 25 | make build 26 | 27 | # Stage to build the driver image 28 | FROM $BASEIMAGE AS final 29 | 30 | # copy in the driver 31 | COPY --from=builder /go/src/csi-isilon / 32 | ENTRYPOINT ["/csi-isilon"] 33 | 34 | LABEL vendor="Dell Technologies" \ 35 | maintainer="Dell Technologies" \ 36 | name="csi-isilon" \ 37 | summary="CSI Driver for Dell EMC PowerScale" \ 38 | description="CSI Driver for provisioning persistent storage from Dell EMC PowerScale" \ 39 | release="1.15.0" \ 40 | version="2.15.0" \ 41 | license="Apache-2.0" 42 | 43 | COPY ./licenses /licenses 44 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Copyright © 2019-2021 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License 12 | 13 | 14 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 15 | # for detailed Gopkg.toml documentation. 16 | # 17 | # Refer to https://github.com/toml-lang/toml for detailed TOML docs. 18 | 19 | [prune] 20 | non-go = true 21 | go-tests = true 22 | unused-packages = true 23 | 24 | [[constraint]] 25 | name = "github.com/dell/gocsi" 26 | version = "1.2.3" 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # default target 2 | all: help 3 | 4 | # include an overrides file, which sets up default values and allows user overrides 5 | include overrides.mk 6 | 7 | # Help target, prints usefule information 8 | help: 9 | @echo 10 | @echo "The following targets are commonly used:" 11 | @echo 12 | @echo "build - Builds the code locally" 13 | @echo "clean - Cleans the local build" 14 | @echo "docker - Builds the code within a golang container and then creates the driver image" 15 | @echo "integration-test - Runs the integration tests. Requires access to an array" 16 | @echo "push - Pushes the built container to a target registry" 17 | @echo "unit-test - Runs the unit tests" 18 | @echo 19 | @make -s overrides-help 20 | 21 | # Clean the build 22 | clean: 23 | rm -f core/core_generated.go go-code-tester 24 | rm -f semver.mk 25 | go clean 26 | 27 | # Dependencies 28 | dependencies: 29 | go generate 30 | go run core/semver/semver.go -f mk >semver.mk 31 | 32 | format: 33 | @gofmt -w -s . 34 | 35 | # Build the driver locally 36 | build: dependencies 37 | GOOS=linux CGO_ENABLED=0 go build 38 | 39 | # Generates the docker container (but does not push) 40 | podman-build: 41 | make -f docker.mk podman-build 42 | 43 | # Generates the docker container without using cache(but does not push) 44 | podman-build-no-cache: 45 | make -f docker.mk podman-build-no-cache 46 | 47 | docker: build 48 | make -f docker.mk docker 49 | 50 | # Pushes container to the repository 51 | podman-build-image-push: podman-build 52 | make -f docker.mk podman-build-image-push 53 | 54 | dev-build-image-push: dev-build 55 | make -f docker.mk docker-build-image-push 56 | 57 | # Windows or Linux; requires no hardware 58 | unit-test: go-code-tester 59 | GITHUB_OUTPUT=/dev/null \ 60 | ./go-code-tester 90 "." "" "true" "" "" "./service/mock|./common/constants|./test/integration|./core|./provider" 61 | 62 | coverage: 63 | cd service; go tool cover -html=c.out -o coverage.html 64 | 65 | # Linux only; populate env.sh with the hardware parameters 66 | integration-test: 67 | ( cd test/integration; sh run.sh ) 68 | 69 | version: 70 | go generate 71 | go run core/semver/semver.go -f mk >semver.mk 72 | make -f docker.mk version 73 | 74 | gosec: 75 | gosec -quiet -log gosec.log -out=gosecresults.csv -fmt=csv ./... 76 | 77 | .PHONY: actions action-help 78 | actions: ## Run all GitHub Action checks that run on a pull request creation 79 | @echo "Running all GitHub Action checks for pull request events..." 80 | @act -l | grep -v ^Stage | grep pull_request | grep -v image_security_scan | awk '{print $$2}' | while read WF; do \ 81 | echo "Running workflow: $${WF}"; \ 82 | act pull_request --no-cache-server --platform ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest --job "$${WF}"; \ 83 | done 84 | 85 | go-code-tester: 86 | curl -o go-code-tester -L https://raw.githubusercontent.com/dell/common-github-actions/main/go-code-tester/entrypoint.sh \ 87 | && chmod +x go-code-tester 88 | 89 | action-help: ## Echo instructions to run one specific workflow locally 90 | @echo "GitHub Workflows can be run locally with the following command:" 91 | @echo "act pull_request --no-cache-server --platform ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest --job " 92 | @echo "" 93 | @echo "Where '' is a Job ID returned by the command:" 94 | @echo "act -l" 95 | @echo "" 96 | @echo "NOTE: if act is not installed, it can be downloaded from https://github.com/nektos/act" 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSI Driver for Dell EMC PowerScale 2 | 3 | [![Go Report Card](https://goreportcard.com/badge/github.com/dell/csi-isilon?style=flat-square)](https://goreportcard.com/report/github.com/dell/csi-isilon) 4 | [![License](https://img.shields.io/github/license/dell/csi-isilon?style=flat-square&color=blue&label=License)](https://github.com/dell/csi-isilon/blob/main/LICENSE) 5 | [![Docker](https://img.shields.io/docker/pulls/dellemc/csi-isilon.svg?logo=docker&style=flat-square&label=Pulls)](https://hub.docker.com/r/dellemc/csi-isilon) 6 | [![Last Release](https://img.shields.io/github/v/release/dell/csi-isilon?label=Latest&style=flat-square&logo=go)](https://github.com/dell/csi-isilon/releases) 7 | 8 | **Repository for CSI Driver for Dell EMC PowerScale** 9 | 10 | ## Description 11 | 12 | CSI Driver for PowerScale is part of the [CSM (Container Storage Modules)](https://github.com/dell/csm) open-source suite of Kubernetes storage enablers for Dell Technology (Dell) products. CSI Driver for PowerScale is a Container Storage Interface (CSI) driver that provides support for provisioning persistent storage using Dell PowerScale storage array. 13 | 14 | This project may be compiled as a stand-alone binary using Golang that, when run, provides a valid CSI endpoint. It also can be used as a precompiled container image. 15 | 16 | ## Table of Contents 17 | 18 | * [Code of Conduct](https://github.com/dell/csm/blob/main/docs/CODE_OF_CONDUCT.md) 19 | * [Maintainer Guide](https://github.com/dell/csm/blob/main/docs/MAINTAINER_GUIDE.md) 20 | * [Committer Guide](https://github.com/dell/csm/blob/main/docs/COMMITTER_GUIDE.md) 21 | * [Contributing Guide](https://github.com/dell/csm/blob/main/docs/CONTRIBUTING.md) 22 | * [List of Adopters](https://github.com/dell/csm/blob/main/docs/ADOPTERS.md) 23 | * [Support](#support) 24 | * [Security](https://github.com/dell/csm/blob/main/docs/SECURITY.md) 25 | * [Building](#building) 26 | * [Runtime Dependecies](#runtime-dependencies) 27 | * [Documentation](#documentation) 28 | 29 | ## Support 30 | For any issues, questions or feedback, please contact [Dell support](https://www.dell.com/support/incidents-online/en-us/contactus/product/container-storage-modules). 31 | 32 | ## Building 33 | 34 | This project is a Go module (see golang.org Module information for explanation). 35 | The dependencies for this project are in the go.mod file. 36 | 37 | To build the source, execute `make clean build`. 38 | 39 | To run unit tests, execute `make unit-test`. 40 | 41 | To build a podman based image, execute `make podman-build`. 42 | 43 | You can run an integration test on a Linux system by populating the env files at `test/integration/` with values for your Dell EMC PowerScale systems and then run "`make integration-test`". 44 | 45 | ## Runtime Dependencies 46 | 47 | Both the Controller and the Node portions of the driver can only be run on nodes which have network connectivity to a “`PowerScale Cluster`” (which is used by the driver). 48 | 49 | ## Documentation 50 | 51 | For more detailed information on the driver, please refer to [Container Storage Modules documentation](https://dell.github.io/csm-docs/). 52 | 53 | -------------------------------------------------------------------------------- /common/constants/consts.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/sirupsen/logrus" 7 | ) 8 | 9 | /* 10 | Copyright (c) 2019-2022 Dell Inc, or its subsidiaries. 11 | 12 | Licensed under the Apache License, Version 2.0 (the "License"); 13 | you may not use this file except in compliance with the License. 14 | You may obtain a copy of the License at 15 | 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | Unless required by applicable law or agreed to in writing, software 19 | distributed under the License is distributed on an "AS IS" BASIS, 20 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | See the License for the specific language governing permissions and 22 | limitations under the License. 23 | */ 24 | 25 | const ( 26 | // PluginName is the name of the CSI plug-in. 27 | PluginName = "csi-isilon.dellemc.com" 28 | 29 | // DefaultAccessZone is "System" 30 | DefaultAccessZone = "System" 31 | // ModeNode is csi driver's "mode "deployment mode 32 | ModeNode = "node" 33 | // ModeController is csi driver's "controller "deployment mode 34 | ModeController = "controller" 35 | 36 | // DefaultVolumeSizeInBytes is default volume sgolang/protobuf/blob/master/ptypesize to create on an Isilon 37 | // cluster when no size is given, expressed in bytes 38 | DefaultVolumeSizeInBytes = 3 * BytesInGiB 39 | 40 | // BytesInGiB is the number of bytes in a gigabyte 41 | BytesInGiB = 1024 * 1024 * 1024 42 | // TRUE constant 43 | TRUE = "TRUE" 44 | // FALSE constant 45 | FALSE = "FALSE" 46 | 47 | // DefaultPortNumber is the port number in default to set the HTTPS port number of the Isilon OneFS API server 48 | DefaultPortNumber = "8080" 49 | 50 | // DefaultIsiPath is the default isiPath which will be used if there's 51 | // no proper isiPath value set in neither storageclass.yaml nor values.yaml 52 | DefaultIsiPath = "/ifs" 53 | 54 | // DefaultIsiVolumePathPermissions are the default permissions for volume directory path 55 | DefaultIsiVolumePathPermissions = "0777" 56 | 57 | // MaxIsiConnRetries is the max number of retries to validate connection to PowerScale Array 58 | MaxIsiConnRetries = 10 59 | 60 | // KubeConfig of kubernetes cluster 61 | KubeConfig = "KUBECONFIG" 62 | 63 | // IsilonConfigFile isilon-creds file with credential info of isilon clusters 64 | IsilonConfigFile = "/isilon-configs/config" 65 | 66 | // DefaultLogLevel for csi logs 67 | DefaultLogLevel = logrus.DebugLevel 68 | 69 | // ParamCSILogLevel csi driver log level 70 | ParamCSILogLevel = "CSI_LOG_LEVEL" 71 | 72 | // DefaultPodmonAPIPortNumber is the port number in default to expose internal health APIs 73 | DefaultPodmonAPIPortNumber = "8083" 74 | 75 | // DefaultPodmonPollRate is the default polling frequency to check for array connectivity 76 | DefaultPodmonPollRate = 60 77 | 78 | // ParamAZReconcileInterval interval to monitor and reconcile network interface labels on nodes 79 | ParamAZReconcileInterval = "AZ_RECONCILE_INTERVAL" 80 | 81 | // DefaultAZReconcileInterval default interval to monitor and reconcile network interface labels on nodes 82 | DefaultAZReconcileInterval = time.Duration(1 * time.Hour) 83 | ) 84 | -------------------------------------------------------------------------------- /common/k8sutils/k8sutils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package k8sutils 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | "time" 24 | 25 | "github.com/dell/gofsutil" 26 | "github.com/kubernetes-csi/csi-lib-utils/leaderelection" 27 | "google.golang.org/grpc/codes" 28 | "google.golang.org/grpc/status" 29 | "k8s.io/client-go/kubernetes" 30 | "k8s.io/client-go/rest" 31 | "k8s.io/client-go/tools/clientcmd" 32 | ) 33 | 34 | var ( 35 | buildConfigFromFlags = clientcmd.BuildConfigFromFlags 36 | newForConfig = kubernetes.NewForConfig 37 | inClusterConfig = rest.InClusterConfig 38 | ) 39 | 40 | var fsInfo = func(ctx context.Context, path string) (int64, int64, int64, int64, int64, int64, error) { 41 | return gofsutil.FsInfo(ctx, path) 42 | } 43 | 44 | type leaderElection interface { 45 | Run() error 46 | WithNamespace(namespace string) 47 | } 48 | 49 | // CreateKubeClientSet - Returns kubeclient set 50 | func CreateKubeClientSet(kubeconfig string) (*kubernetes.Clientset, error) { 51 | var clientset *kubernetes.Clientset 52 | if kubeconfig != "" { 53 | // use the current context in kubeconfig 54 | config, err := buildConfigFromFlags("", kubeconfig) 55 | if err != nil { 56 | return nil, err 57 | } 58 | // create the clientset 59 | clientset, err = newForConfig(config) 60 | if err != nil { 61 | return nil, err 62 | } 63 | } else { 64 | config, err := inClusterConfig() 65 | if err != nil { 66 | return nil, err 67 | } 68 | // creates the clientset 69 | clientset, err = newForConfig(config) 70 | if err != nil { 71 | return nil, err 72 | } 73 | } 74 | return clientset, nil 75 | } 76 | 77 | // LeaderElection - Initialize leader election 78 | func LeaderElection(clientset *kubernetes.Clientset, lockName string, namespace string, 79 | leaderElectionRenewDeadline, leaderElectionLeaseDuration, leaderElectionRetryPeriod time.Duration, runFunc func(ctx context.Context), 80 | ) { 81 | le := leaderelection.NewLeaderElection(clientset, lockName, runFunc) 82 | le.WithNamespace(namespace) 83 | le.WithLeaseDuration(leaderElectionLeaseDuration) 84 | le.WithRenewDeadline(leaderElectionRenewDeadline) 85 | le.WithRetryPeriod(leaderElectionRetryPeriod) 86 | if err := le.Run(); err != nil { 87 | _, _ = fmt.Fprintf(os.Stderr, "failed to initialize leader election: %v", err) 88 | os.Exit(1) 89 | } 90 | } 91 | 92 | // GetStats - Returns the stats for the volume mounted on given volume path 93 | func GetStats(ctx context.Context, volumePath string) (int64, int64, int64, int64, int64, int64, error) { 94 | availableBytes, totalBytes, usedBytes, totalInodes, freeInodes, usedInodes, err := fsInfo(ctx, volumePath) 95 | if err != nil { 96 | return 0, 0, 0, 0, 0, 0, status.Error(codes.Internal, fmt.Sprintf( 97 | "failed to get volume stats: %s", err)) 98 | } 99 | return availableBytes, totalBytes, usedBytes, totalInodes, freeInodes, usedInodes, err 100 | } 101 | -------------------------------------------------------------------------------- /common/utils/fromcontext/from-context.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package fromcontext 17 | 18 | import ( 19 | "context" 20 | "fmt" 21 | "strconv" 22 | 23 | "github.com/dell/csi-isilon/v2/common/utils/logging" 24 | csictx "github.com/dell/gocsi/context" 25 | "gopkg.in/yaml.v3" 26 | ) 27 | 28 | // GetBoolean parses an environment variable into a boolean value. If an error is encountered, default is set to false, and error is logged 29 | func GetBoolean(ctx context.Context, key string) bool { 30 | log := logging.GetRunIDLogger(ctx) 31 | if val, ok := csictx.LookupEnv(ctx, key); ok { 32 | b, err := strconv.ParseBool(val) 33 | if err != nil { 34 | log.WithField(key, val).Debugf( 35 | "invalid boolean value for '%s', defaulting to false", key) 36 | return false 37 | } 38 | return b 39 | } 40 | return false 41 | } 42 | 43 | // GetArray parses an environment variable into an array of string 44 | func GetArray(ctx context.Context, key string) ([]string, error) { 45 | var values []string 46 | 47 | if val, ok := csictx.LookupEnv(ctx, key); ok { 48 | err := yaml.Unmarshal([]byte(val), &values) 49 | if err != nil { 50 | return values, fmt.Errorf("invalid array value for '%s'", key) 51 | } 52 | } 53 | return values, nil 54 | } 55 | 56 | // GetUint parses an environment variable into a uint value. If an error is encountered, default is set to 0, and error is logged 57 | func GetUint(ctx context.Context, key string) uint { 58 | log := logging.GetRunIDLogger(ctx) 59 | if val, ok := csictx.LookupEnv(ctx, key); ok { 60 | i, err := strconv.ParseUint(val, 10, 0) 61 | if err != nil { 62 | log.WithField(key, val).Debugf( 63 | "invalid int value for '%s', defaulting to 0", key) 64 | return 0 65 | } 66 | return uint(i) 67 | } 68 | return 0 69 | } 70 | 71 | // GetInt64 parses an environment variable into an int64 value. 72 | func GetInt64(ctx context.Context, key string) (int64, error) { 73 | if val, ok := csictx.LookupEnv(ctx, key); ok { 74 | i, err := strconv.ParseInt(val, 10, 64) 75 | if err != nil { 76 | return 0, fmt.Errorf("invalid int64 value '%v' specified for '%s'", val, key) 77 | } 78 | return i, nil 79 | } 80 | return 0, nil 81 | } 82 | -------------------------------------------------------------------------------- /common/utils/identifiers/fqdn.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package identifiers 17 | 18 | import ( 19 | "context" 20 | "errors" 21 | "net" 22 | "strings" 23 | 24 | "github.com/Showmax/go-fqdn" 25 | "github.com/dell/csi-isilon/v2/common/utils/logging" 26 | ) 27 | 28 | // GetFQDNByIP returns the FQDN based on the parsed ip address 29 | func GetFQDNByIP(ctx context.Context, ip string) (string, error) { 30 | log := logging.GetRunIDLogger(ctx) 31 | names, err := net.LookupAddr(ip) 32 | if err != nil { 33 | log.Debugf("error getting FQDN: '%s'", err) 34 | return "", err 35 | } 36 | // The first one is FQDN 37 | FQDN := strings.TrimSuffix(names[0], ".") 38 | return FQDN, nil 39 | } 40 | 41 | // GetOwnFQDN returns the FQDN of the node or controller itself 42 | func GetOwnFQDN() (string, error) { 43 | nodeFQDN := fqdn.Get() 44 | if nodeFQDN == "unknown" { 45 | return "", errors.New("cannot get FQDN") 46 | } 47 | return nodeFQDN, nil 48 | } 49 | -------------------------------------------------------------------------------- /common/utils/identifiers/fqdn_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2021-2024 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package identifiers 20 | 21 | import ( 22 | "context" 23 | "testing" 24 | 25 | "github.com/stretchr/testify/assert" 26 | ) 27 | 28 | func TestGetOwnFQDN(t *testing.T) { 29 | fqdn, err := GetOwnFQDN() 30 | if err != nil { 31 | t.Skip("Skipping test: Unable to get FQDN") 32 | } 33 | assert.NoError(t, err) 34 | assert.NotEmpty(t, fqdn) 35 | } 36 | 37 | func TestGetFQDNByIP(t *testing.T) { 38 | ctx := context.Background() 39 | 40 | t.Run("Valid IP with FQDN", func(t *testing.T) { 41 | // Use a public IP that is likely to return a valid FQDN 42 | fqdn, err := GetFQDNByIP(ctx, "8.8.8.8") // Google's public DNS server 43 | if err == nil { 44 | assert.NotEmpty(t, fqdn, "Expected a non-empty FQDN") 45 | } 46 | }) 47 | 48 | t.Run("Invalid IP should return error", func(t *testing.T) { 49 | fqdn, err := GetFQDNByIP(ctx, "256.256.256.256") // Invalid IP 50 | assert.Error(t, err, "Expected an error for invalid IP") 51 | assert.Empty(t, fqdn, "Expected empty FQDN for invalid IP") 52 | }) 53 | 54 | t.Run("Non-resolvable IP should return error", func(t *testing.T) { 55 | fqdn, err := GetFQDNByIP(ctx, "192.0.2.1") // IP in TEST-NET-1 (unlikely to resolve) 56 | assert.Error(t, err, "Expected an error for non-resolvable IP") 57 | assert.Empty(t, fqdn, "Expected empty FQDN for non-resolvable IP") 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /common/utils/identifiers/node.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package identifiers 17 | 18 | import ( 19 | "context" 20 | "fmt" 21 | "regexp" 22 | 23 | "github.com/dell/csi-isilon/v2/common/utils/logging" 24 | ) 25 | 26 | const ( 27 | // NodeIDSeparator is the separator that separates node name and IP Address 28 | NodeIDSeparator = "=#=#=" 29 | 30 | // DummyHostNodeID is nodeID used for adding dummy client in client field of export 31 | DummyHostNodeID = "localhost=#=#=localhost=#=#=127.0.0.1" 32 | ) 33 | 34 | // NodeIDPattern is the regex pattern that identifies the NodeID 35 | var NodeIDPattern = regexp.MustCompile(fmt.Sprintf("^(.+)%s(.+)%s(.+)$", NodeIDSeparator, NodeIDSeparator)) 36 | 37 | // ParseNodeID parses NodeID to node name, node FQDN and IP address using pattern '^(.+)=#=#=(.+)=#=#=(.+)' 38 | func ParseNodeID(ctx context.Context, nodeID string) (string, string, string, error) { 39 | log := logging.GetRunIDLogger(ctx) 40 | 41 | matches := NodeIDPattern.FindStringSubmatch(nodeID) 42 | 43 | if len(matches) < 4 { 44 | return "", "", "", fmt.Errorf("node ID '%s' cannot match the expected '^(.+)=#=#=(.+)=#=#=(.+)$' pattern", nodeID) 45 | } 46 | 47 | log.Debugf("Node ID '%s' parsed into node name '%s', node FQDN '%s' and IP address '%s'", 48 | nodeID, matches[1], matches[2], matches[3]) 49 | 50 | return matches[1], matches[2], matches[3], nil 51 | } 52 | -------------------------------------------------------------------------------- /common/utils/identifiers/node_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2021-2024 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package identifiers 20 | 21 | import ( 22 | "context" 23 | "testing" 24 | ) 25 | 26 | func TestParseNodeID(t *testing.T) { 27 | tests := []struct { 28 | name string 29 | nodeID string 30 | wantName string 31 | wantFQDN string 32 | wantIP string 33 | wantErr bool 34 | }{ 35 | { 36 | name: "Valid Node ID", 37 | nodeID: "node1=#=#=fqdn.example.com=#=#=192.168.1.1", 38 | wantName: "node1", 39 | wantFQDN: "fqdn.example.com", 40 | wantIP: "192.168.1.1", 41 | wantErr: false, 42 | }, 43 | { 44 | name: "Invalid Node ID - Missing Sections", 45 | nodeID: "node1=#=#=fqdn.example.com", 46 | wantErr: true, 47 | }, 48 | { 49 | name: "Invalid Node ID - Empty String", 50 | nodeID: "", 51 | wantErr: true, 52 | }, 53 | } 54 | 55 | for _, tt := range tests { 56 | t.Run(tt.name, func(t *testing.T) { 57 | ctx := context.Background() 58 | gotName, gotFQDN, gotIP, err := ParseNodeID(ctx, tt.nodeID) 59 | 60 | if (err != nil) != tt.wantErr { 61 | t.Errorf("ParseNodeID() error = %v, wantErr %v", err, tt.wantErr) 62 | } 63 | if gotName != tt.wantName { 64 | t.Errorf("ParseNodeID() gotName = %v, want %v", gotName, tt.wantName) 65 | } 66 | if gotFQDN != tt.wantFQDN { 67 | t.Errorf("ParseNodeID() gotFQDN = %v, want %v", gotFQDN, tt.wantFQDN) 68 | } 69 | if gotIP != tt.wantIP { 70 | t.Errorf("ParseNodeID() gotIP = %v, want %v", gotIP, tt.wantIP) 71 | } 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /common/utils/identifiers/snapshot.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package identifiers 17 | 18 | import ( 19 | "context" 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/dell/csi-isilon/v2/common/utils/logging" 24 | ) 25 | 26 | // SnapshotIDSeparator is the separator that separates snapshot id and cluster name (two components that a normalized snapshot ID is comprised of) 27 | const SnapshotIDSeparator = "=_=_=" 28 | 29 | // GetNormalizedSnapshotID combines snapshotID ID and cluster name and access zone to form the normalized snapshot ID 30 | // e.g. 12345 + cluster1 + accessZone => 12345=_=_=cluster1=_=_=zone1 31 | func GetNormalizedSnapshotID(ctx context.Context, snapshotID, clusterName, accessZone string) string { 32 | log := logging.GetRunIDLogger(ctx) 33 | 34 | snapID := fmt.Sprintf("%s%s%s%s%s", snapshotID, SnapshotIDSeparator, clusterName, SnapshotIDSeparator, accessZone) 35 | 36 | log.Debugf("combined snapshot id '%s' access zone '%s' and cluster name '%s' to form normalized snapshot ID '%s'", 37 | snapshotID, accessZone, clusterName, snapID) 38 | 39 | return snapID 40 | } 41 | 42 | // ParseNormalizedSnapshotID parses the normalized snapshot ID(using SnapshotIDSeparator) to extract the snapshot ID and cluster name(optional) that make up the normalized snapshot ID 43 | // e.g. 12345 => 12345, "" 44 | // e.g. 12345=_=_=cluster1=_=_=zone => 12345, cluster1, zone 45 | func ParseNormalizedSnapshotID(ctx context.Context, snapID string) (string, string, string, error) { 46 | log := logging.GetRunIDLogger(ctx) 47 | tokens := strings.Split(snapID, SnapshotIDSeparator) 48 | if len(tokens) < 1 { 49 | return "", "", "", fmt.Errorf("snapshot ID '%s' cannot be split into tokens", snapID) 50 | } 51 | 52 | snapshotID := tokens[0] 53 | var clusterName, accessZone string 54 | if len(tokens) > 1 { 55 | clusterName = tokens[1] 56 | if len(tokens) > 2 { 57 | accessZone = tokens[2] 58 | } else { 59 | return "", "", "", fmt.Errorf("access zone not found in snapshot ID '%s'", snapID) 60 | } 61 | } 62 | 63 | log.Debugf("normalized snapshot ID '%s' parsed into snapshot ID '%s' and cluster name '%s'", 64 | snapID, snapshotID, clusterName) 65 | 66 | return snapshotID, clusterName, accessZone, nil 67 | } 68 | -------------------------------------------------------------------------------- /common/utils/identifiers/snapshot_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2021-2024 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package identifiers 20 | 21 | import ( 22 | "context" 23 | "fmt" 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestParseNormalizedSnapshotID(t *testing.T) { 30 | ctx := context.Background() 31 | 32 | snapshotID, clusterName, accessZone, err := ParseNormalizedSnapshotID(ctx, "284=_=_=cluster1=_=_=System") 33 | 34 | assert.Equal(t, "284", snapshotID) 35 | assert.Equal(t, "cluster1", clusterName) 36 | assert.Equal(t, "System", accessZone) 37 | assert.Nil(t, err) 38 | 39 | expectedError := "access zone not found in snapshot ID '284=_=_=cluster1'" 40 | _, _, _, err = ParseNormalizedSnapshotID(ctx, "284=_=_=cluster1") 41 | assert.NotNil(t, err) 42 | assert.Contains(t, err.Error(), expectedError) 43 | } 44 | 45 | func TestGetNormalizedSnapshotID(t *testing.T) { 46 | ctx := context.Background() 47 | 48 | // Test case 1: Valid input 49 | snapshotID := "12345" 50 | clusterName := "cluster1" 51 | accessZone := "zone1" 52 | 53 | expectedSnapID := fmt.Sprintf("%s%s%s%s%s", snapshotID, SnapshotIDSeparator, clusterName, SnapshotIDSeparator, accessZone) 54 | actualSnapID := GetNormalizedSnapshotID(ctx, snapshotID, clusterName, accessZone) 55 | 56 | assert.Equal(t, expectedSnapID, actualSnapID, "Generated snapshot ID should match the expected format") 57 | 58 | // Test case 2: Edge case - Empty values 59 | emptySnapID := GetNormalizedSnapshotID(ctx, "", "", "") 60 | expectedEmptySnapID := fmt.Sprintf("%s%s%s%s%s", "", SnapshotIDSeparator, "", SnapshotIDSeparator, "") 61 | assert.Equal(t, expectedEmptySnapID, emptySnapID, "Empty values should still generate a valid but empty formatted string") 62 | 63 | // Test case 3: Special characters in input 64 | specialSnapID := GetNormalizedSnapshotID(ctx, "snap@123", "cluster#name", "zone!1") 65 | expectedSpecialSnapID := fmt.Sprintf("%s%s%s%s%s", "snap@123", SnapshotIDSeparator, "cluster#name", SnapshotIDSeparator, "zone!1") 66 | assert.Equal(t, expectedSpecialSnapID, specialSnapID, "Snapshot ID should handle special characters properly") 67 | } 68 | -------------------------------------------------------------------------------- /common/utils/identifiers/uuid.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package identifiers 17 | 18 | import ( 19 | "github.com/dell/csi-isilon/v2/common/utils/logging" 20 | "github.com/google/uuid" 21 | ) 22 | 23 | // GetNewUUID generates a UUID 24 | func GetNewUUID() (string, error) { 25 | log := logging.GetLogger() 26 | id, err := uuid.NewUUID() 27 | if err != nil { 28 | log.Errorf("error generating UUID : '%s'", err) 29 | return "", err 30 | } 31 | 32 | return id.String(), nil 33 | } 34 | -------------------------------------------------------------------------------- /common/utils/identifiers/uuid_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2021-2024 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package identifiers 20 | 21 | import ( 22 | "testing" 23 | 24 | "github.com/google/uuid" 25 | ) 26 | 27 | func TestGetNewUUID(t *testing.T) { 28 | id, err := GetNewUUID() 29 | if err != nil { 30 | t.Errorf("expected no error, got %v", err) 31 | } 32 | 33 | if _, err := uuid.Parse(id); err != nil { 34 | t.Errorf("expected valid UUID, got %s", id) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/utils/identifiers/volume.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package identifiers 17 | 18 | import ( 19 | "context" 20 | "fmt" 21 | "strconv" 22 | "strings" 23 | 24 | "github.com/dell/csi-isilon/v2/common/utils/logging" 25 | ) 26 | 27 | // VolumeIDSeparator is the separator that separates volume name and export ID (two components that a normalized volume ID is comprised of) 28 | const VolumeIDSeparator = "=_=_=" 29 | 30 | // GetNormalizedVolumeID combines volume name (i.e. the directory name), export ID, access zone and clusterName to form the normalized volume ID 31 | // e.g. k8s-e89c9d089e + 19 + csi0zone + cluster1 => k8s-e89c9d089e=_=_=19=_=_=csi0zone=_=_=cluster1 32 | func GetNormalizedVolumeID(ctx context.Context, volName string, exportID int, accessZone, clusterName string) string { 33 | log := logging.GetRunIDLogger(ctx) 34 | 35 | volID := fmt.Sprintf("%s%s%s%s%s%s%s", volName, VolumeIDSeparator, strconv.Itoa(exportID), VolumeIDSeparator, accessZone, VolumeIDSeparator, clusterName) 36 | 37 | log.Debugf("combined volume name '%s' with export ID '%d', access zone '%s' and cluster name '%s' to form volume ID '%s'", 38 | volName, exportID, accessZone, clusterName, volID) 39 | 40 | return volID 41 | } 42 | 43 | // ParseNormalizedVolumeID parses the volume ID(using VolumeIDSeparator) to extract the volume name, export ID, access zone and cluster name(optional) that make up the volume ID 44 | // e.g. k8s-e89c9d089e=_=_=19=_=_=csi0zone => k8s-e89c9d089e, 19, csi0zone, "" 45 | // e.g. k8s-e89c9d089e=_=_=19=_=_=csi0zone=_=_=cluster1 => k8s-e89c9d089e, 19, csi0zone, cluster1 46 | func ParseNormalizedVolumeID(ctx context.Context, volID string) (string, int, string, string, error) { 47 | log := logging.GetRunIDLogger(ctx) 48 | tokens := strings.Split(volID, VolumeIDSeparator) 49 | if len(tokens) < 3 { 50 | return "", 0, "", "", fmt.Errorf("volume ID '%s' cannot be split into tokens", volID) 51 | } 52 | 53 | volumeName := tokens[0] 54 | 55 | exportID, err := strconv.Atoi(tokens[1]) 56 | if err != nil { 57 | return "", 0, "", "", err 58 | } 59 | 60 | accessZone := tokens[2] 61 | 62 | var clusterName string 63 | if len(tokens) > 3 { 64 | clusterName = tokens[3] 65 | } 66 | 67 | log.Debugf("volume ID '%s' parsed into volume name '%s', export ID '%d', access zone '%s' and cluster name '%s'", 68 | volID, volumeName, exportID, accessZone, clusterName) 69 | 70 | return volumeName, exportID, accessZone, clusterName, nil 71 | } 72 | -------------------------------------------------------------------------------- /common/utils/identifiers/volume_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright © 2021-2024 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package identifiers 20 | 21 | import ( 22 | "context" 23 | "fmt" 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestParseNormalizedVolumeID(t *testing.T) { 30 | ctx := context.Background() 31 | 32 | volName, exportID, accessZone, clusterName, err := ParseNormalizedVolumeID(ctx, "k8s-e89c9d089e=_=_=19=_=_=csi0zone=_=_=cluster1") 33 | 34 | assert.Equal(t, "k8s-e89c9d089e", volName) 35 | assert.Equal(t, 19, exportID) 36 | assert.Equal(t, "csi0zone", accessZone) 37 | assert.Equal(t, "cluster1", clusterName) 38 | assert.Nil(t, err) 39 | 40 | _, _, _, _, err = ParseNormalizedVolumeID(ctx, "totally bogus") 41 | assert.NotNil(t, err) 42 | 43 | _, _, _, _, err = ParseNormalizedVolumeID(ctx, "k8s-e89c9d089e=_=_=not_an_integer=_=_=csi0zone") 44 | assert.NotNil(t, err) 45 | } 46 | 47 | func TestGetNormalizedVolumeID(t *testing.T) { 48 | ctx := context.Background() 49 | 50 | // Test case 1: Valid input 51 | volName := "k8s-e89c9d089e" 52 | exportID := 19 53 | accessZone := "csi0zone" 54 | clusterName := "cluster1" 55 | 56 | expectedVolID := fmt.Sprintf("%s%s%d%s%s%s%s", volName, VolumeIDSeparator, exportID, VolumeIDSeparator, accessZone, VolumeIDSeparator, clusterName) 57 | actualVolID := GetNormalizedVolumeID(ctx, volName, exportID, accessZone, clusterName) 58 | 59 | assert.Equal(t, expectedVolID, actualVolID, "Generated volume ID should match the expected format") 60 | 61 | // Test case 2: Edge case - Empty values 62 | emptyVolID := GetNormalizedVolumeID(ctx, "", 0, "", "") 63 | expectedEmptyVolID := fmt.Sprintf("%s%s%d%s%s%s%s", "", VolumeIDSeparator, 0, VolumeIDSeparator, "", VolumeIDSeparator, "") 64 | assert.Equal(t, expectedEmptyVolID, emptyVolID, "Empty values should still generate a valid but empty formatted string") 65 | 66 | // Test case 3: Special characters in input 67 | specialCharVolID := GetNormalizedVolumeID(ctx, "vol@name", 42, "zone#1", "cluster!name") 68 | expectedSpecialVolID := fmt.Sprintf("%s%s%d%s%s%s%s", "vol@name", VolumeIDSeparator, 42, VolumeIDSeparator, "zone#1", VolumeIDSeparator, "cluster!name") 69 | assert.Equal(t, expectedSpecialVolID, specialCharVolID, "Volume ID should handle special characters properly") 70 | } 71 | -------------------------------------------------------------------------------- /common/utils/string-utils/string-utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package stringutils 17 | 18 | // IsStringInSlice checks if a string is an element of a string slice 19 | func IsStringInSlice(str string, list []string) bool { 20 | for _, b := range list { 21 | if b == str { 22 | return true 23 | } 24 | } 25 | 26 | return false 27 | } 28 | 29 | // IsStringInSlices checks if a string is an element of a any of the string slices 30 | func IsStringInSlices(str string, list ...[]string) bool { 31 | for _, strs := range list { 32 | if IsStringInSlice(str, strs) { 33 | return true 34 | } 35 | } 36 | 37 | return false 38 | } 39 | 40 | // RemoveStringFromSlice returns a slice that is a copy of the input "list" slice with the input "str" string removed 41 | func RemoveStringFromSlice(str string, list []string) []string { 42 | result := make([]string, 0) 43 | 44 | for _, v := range list { 45 | if str != v { 46 | result = append(result, v) 47 | } 48 | } 49 | 50 | return result 51 | } 52 | 53 | // RemoveStringsFromSlice generates a slice that is a copy of the input "list" slice with elements from the input "strs" slice removed 54 | func RemoveStringsFromSlice(filters []string, list []string) []string { 55 | result := make([]string, 0) 56 | 57 | for _, str := range list { 58 | if !IsStringInSlice(str, filters) { 59 | result = append(result, str) 60 | } 61 | } 62 | 63 | return result 64 | } 65 | 66 | // RemoveSurroundingQuotes removes the surrounding double quotes of a given string (if there are no surrounding quotes, do nothing) 67 | func RemoveSurroundingQuotes(s string) string { 68 | if len(s) > 0 && s[0] == '"' { 69 | s = s[1:] 70 | } 71 | if len(s) > 0 && s[len(s)-1] == '"' { 72 | s = s[:len(s)-1] 73 | } 74 | 75 | return s 76 | } 77 | 78 | // CombineTwoStrings combines two string variables isolated by defined sign 79 | func CombineTwoStrings(s1 string, s2 string, sign string) string { 80 | s := s1 + sign + s2 81 | return s 82 | } 83 | -------------------------------------------------------------------------------- /core/.gitignore: -------------------------------------------------------------------------------- 1 | core_generated.go 2 | -------------------------------------------------------------------------------- /core/core.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | /* 4 | Copyright (c) 2019 Dell Inc, or its subsidiaries. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | //go:generate go run semver/semver.go -f semver.tpl -o core_generated.go 19 | 20 | import "time" 21 | 22 | var ( 23 | // SemVer is the semantic version. 24 | SemVer = "unknown" 25 | 26 | // CommitSha7 is the short version of the commit hash from which 27 | // this program was built. 28 | CommitSha7 string 29 | 30 | // CommitSha32 is the long version of the commit hash from which 31 | // this program was built. 32 | CommitSha32 string 33 | 34 | // CommitTime is the commit timestamp of the commit from which 35 | // this program was built. 36 | CommitTime time.Time 37 | ) 38 | -------------------------------------------------------------------------------- /core/semver.tpl: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "time" 4 | 5 | func init() { 6 | SemVer = "{{.SemVer}}" 7 | CommitSha7 = "{{.Sha7}}" 8 | CommitSha32 = "{{.Sha32}}" 9 | CommitTime = time.Unix({{.Epoch}}, 0) 10 | } 11 | -------------------------------------------------------------------------------- /dell-csi-helm-installer/.gitignore: -------------------------------------------------------------------------------- 1 | images.manifest 2 | images.tar 3 | -------------------------------------------------------------------------------- /dell-csi-helm-installer/csi-uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 15 | DRIVERDIR="${SCRIPTDIR}/../helm-charts/charts" 16 | PROG="${0}" 17 | DRIVER="csi-isilon" 18 | # export the name of the debug log, so child processes will see it 19 | export DEBUGLOG="${SCRIPTDIR}/uninstall-debug.log" 20 | 21 | declare -a VALIDDRIVERS 22 | 23 | source "$SCRIPTDIR"/common.sh 24 | 25 | if [ -f "${DEBUGLOG}" ]; then 26 | rm -f "${DEBUGLOG}" 27 | fi 28 | 29 | # 30 | # usage will print command execution help and then exit 31 | function usage() { 32 | decho "Help for $PROG" 33 | decho 34 | decho "Usage: $PROG options..." 35 | decho "Options:" 36 | decho " Required" 37 | decho " --namespace[=] Kubernetes namespace to uninstall the CSI driver from" 38 | 39 | decho " Optional" 40 | decho " --release[=] Name to register with helm, default value will match the driver name" 41 | decho " -h Help" 42 | decho 43 | 44 | exit 0 45 | } 46 | 47 | 48 | 49 | # 50 | # validate_params will validate the parameters passed in 51 | function validate_params() { 52 | # make sure the driver was specified 53 | if [ -z "${DRIVER}" ]; then 54 | decho "No driver specified" 55 | exit 1 56 | fi 57 | 58 | # the namespace is required 59 | if [ -z "${NAMESPACE}" ]; then 60 | decho "No namespace specified" 61 | usage 62 | exit 1 63 | fi 64 | } 65 | 66 | 67 | # check_for_driver will see if the driver is installed within the namespace provided 68 | function check_for_driver() { 69 | NUM=$(run_command helm list --namespace "${NAMESPACE}" | grep "^${RELEASE}\b" | wc -l) 70 | if [ "${NUM}" == "0" ]; then 71 | log uninstall_error "The CSI Driver is not installed." 72 | exit 1 73 | fi 74 | } 75 | 76 | while getopts ":h-:" optchar; do 77 | case "${optchar}" in 78 | -) 79 | case "${OPTARG}" in 80 | # NAMESPACE 81 | namespace) 82 | NAMESPACE="${!OPTIND}" 83 | OPTIND=$((OPTIND + 1)) 84 | ;; 85 | namespace=*) 86 | NAMESPACE=${OPTARG#*=} 87 | ;; 88 | # RELEASE 89 | release) 90 | RELEASE="${!OPTIND}" 91 | OPTIND=$((OPTIND + 1)) 92 | ;; 93 | release=*) 94 | RELEASE=${OPTARG#*=} 95 | ;; 96 | *) 97 | decho "Unknown option --${OPTARG}" 98 | decho "For help, run $PROG -h" 99 | exit 1 100 | ;; 101 | esac 102 | ;; 103 | h) 104 | usage 105 | ;; 106 | *) 107 | decho "Unknown option -${OPTARG}" 108 | decho "For help, run $PROG -h" 109 | exit 1 110 | ;; 111 | esac 112 | done 113 | 114 | # by default the NAME of the helm release of the driver is the same as the driver name 115 | RELEASE=$(get_release_name "${DRIVER}") 116 | 117 | # validate the parameters passed in 118 | validate_params 119 | 120 | check_for_driver 121 | run_command helm delete -n "${NAMESPACE}" "${RELEASE}" 122 | if [ $? -ne 0 ]; then 123 | decho "Removal of the CSI Driver was unsuccessful" 124 | exit 1 125 | fi 126 | 127 | decho "Removal of the CSI Driver is in progress." 128 | decho "It may take a few minutes for all pods to terminate." 129 | 130 | -------------------------------------------------------------------------------- /dell-csi-helm-installer/verify-csi-isilon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # 15 | # verify-csi-isilon method 16 | function verify-csi-isilon() { 17 | verify_k8s_versions "1.32" "1.34" 18 | verify_openshift_versions "4.18" "4.19" 19 | verify_namespace "${NS}" 20 | verify_required_secrets "${RELEASE}-creds" 21 | verify_optional_secrets "${RELEASE}-certs" 22 | verify_alpha_snap_resources 23 | verify_snap_requirements 24 | verify_helm_3 25 | verify_helm_values_version "${DRIVER_VERSION}" 26 | verify_authorization_proxy_server 27 | } 28 | -------------------------------------------------------------------------------- /docker.mk: -------------------------------------------------------------------------------- 1 | # docker makefile, included from Makefile, will build/push images with docker or podman 2 | 3 | docker: download-csm-common 4 | $(eval include csm-common.mk) 5 | @echo "Building docker image: $(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 6 | docker build --pull -t "$(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" --build-arg GOPROXY=$(GOPROXY) --build-arg BASEIMAGE=$(CSM_BASEIMAGE) --build-arg GOIMAGE=$(DEFAULT_GOIMAGE) . 7 | 8 | docker-push: 9 | @echo "Pushing: $(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 10 | docker push "$(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 11 | 12 | podman-build: download-csm-common 13 | $(eval include csm-common.mk) 14 | @echo "Building: $(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 15 | @echo "Using Golang Image $(DEFAULT_GOIMAGE)" 16 | $(BUILDER) build --pull $(NOCACHE) -t "$(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" --build-arg GOPROXY=$(GOPROXY) --build-arg BASEIMAGE=$(CSM_BASEIMAGE) --build-arg GOIMAGE=$(DEFAULT_GOIMAGE) . 17 | 18 | podman-build-no-cache: 19 | @echo "Building with --no-cache ..." 20 | @make podman-build NOCACHE=--no-cache 21 | 22 | podman-build-image-push: 23 | @echo "Pushing: $(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 24 | $(BUILDER) push "$(REGISTRY)/$(IMAGENAME):$(IMAGETAG)" 25 | 26 | version: 27 | @echo "MAJOR $(MAJOR) MINOR $(MINOR) PATCH $(PATCH) BUILD ${BUILD} TYPE ${TYPE} RELNOTE $(RELNOTE) SEMVER $(SEMVER)" 28 | @echo "Target Version: $(VERSION)" 29 | 30 | download-csm-common: 31 | curl -O -L https://raw.githubusercontent.com/dell/csm/main/config/csm-common.mk -------------------------------------------------------------------------------- /overrides.mk: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2023 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License 12 | 13 | # overrides file 14 | # this file, included from the Makefile, will overlay default values with environment variables 15 | # 16 | 17 | # DEFAULT values 18 | DEFAULT_GOVERSION="1.21" 19 | DEFAULT_REGISTRY="" 20 | DEFAULT_IMAGENAME="isilon" 21 | DEFAULT_BUILDSTAGE="final" 22 | ifeq ($(origin BUILD_TIMESTAMP), undefined) 23 | BUILD_TIMESTAMP := $(shell date +%Y%m%d%H%M%S) 24 | endif 25 | DEFAULT_IMAGETAG=$(BUILD_TIMESTAMP) 26 | DEFAULT_GOPROXY="" 27 | 28 | # set the GOVERSION if needed 29 | ifeq ($(GOVERSION),) 30 | export GOVERSION="$(DEFAULT_GOVERSION)" 31 | endif 32 | 33 | # set the REGISTRY if needed 34 | ifeq ($(REGISTRY),) 35 | export REGISTRY="$(DEFAULT_REGISTRY)" 36 | endif 37 | 38 | # set the IMAGENAME if needed 39 | ifeq ($(IMAGENAME),) 40 | export IMAGENAME="$(DEFAULT_IMAGENAME)" 41 | endif 42 | 43 | # set the IMAGETAG if needed 44 | ifeq ($(IMAGETAG),) 45 | export IMAGETAG="$(DEFAULT_IMAGETAG)" 46 | endif 47 | 48 | # set the GOPROXY if needed 49 | ifeq ($(GOPROXY),) 50 | export GOPROXY="$(DEFAULT_GOPROXY)" 51 | endif 52 | 53 | # figure out if podman or docker should be used (use podman if found) 54 | ifneq (, $(shell which podman 2>/dev/null)) 55 | export BUILDER=podman 56 | else 57 | export BUILDER=docker 58 | endif 59 | 60 | # target to print some help regarding these overrides and how to use them 61 | overrides-help: 62 | @echo 63 | @echo "The following environment variables can be set to control the build" 64 | @echo 65 | @echo "GOVERSION - The version of Go to build with, default is: $(DEFAULT_GOVERSION)" 66 | @echo " Current setting is: $(GOVERSION)" 67 | @echo "REGISTRY - The registry to push images to, default is: $(DEFAULT_REGISTRY)" 68 | @echo " Current setting is: $(REGISTRY)" 69 | @echo "IMAGENAME - The image name to be built, defaut is: $(DEFAULT_IMAGENAME)" 70 | @echo " Current setting is: $(IMAGENAME)" 71 | @echo "IMAGETAG - The image tag to be built, default is an empty string which will determine the tag by examining annotated tags in the repo." 72 | @echo " Current setting is: $(IMAGETAG)" 73 | @echo "GOPROXY - The goproxy to be used for resolving dependencies, default is: $(DEFAULT_GOPROXY)" 74 | @echo " Current setting is: $(GOPROXY)" 75 | @echo 76 | -------------------------------------------------------------------------------- /provider/provider.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | /* 4 | Copyright (c) 2021-2022 Dell Inc, or its subsidiaries. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | import ( 20 | "github.com/dell/csi-isilon/v2/common/utils/logging" 21 | csiutils "github.com/dell/csi-isilon/v2/csi-utils" 22 | "github.com/dell/csi-isilon/v2/service" 23 | "github.com/dell/csi-isilon/v2/service/interceptor" 24 | "github.com/dell/gocsi" 25 | "google.golang.org/grpc" 26 | ) 27 | 28 | // New returns a new Storage Plug-in Provider. 29 | func New() gocsi.StoragePluginProvider { 30 | log := logging.GetLogger() 31 | 32 | // TODO during the test, for some reason, when the controller & node pods start, 33 | // the sock files always exist right from the beginning, even if you manually 34 | // remove them prior to using helm to install the csi driver. Need to find out why. 35 | // For the time being, manually remove the sock files right at the beginning to 36 | // avoid the "...address is in use..." error 37 | if err := csiutils.RemoveExistingCSISockFile(); err != nil { 38 | log.Error("failed to call utils.RemoveExistingCSISockFile") 39 | } 40 | // Get the MaxConcurrentStreams server option and configure it. 41 | maxStreams := grpc.MaxConcurrentStreams(8) 42 | serverOptions := make([]grpc.ServerOption, 1) 43 | serverOptions[0] = maxStreams 44 | svc := service.New() 45 | 46 | interList := []grpc.UnaryServerInterceptor{ 47 | interceptor.NewCustomSerialLock(), 48 | interceptor.NewRewriteRequestIDInterceptor(), 49 | } 50 | return &gocsi.StoragePlugin{ 51 | Controller: svc, 52 | Identity: svc, 53 | Node: svc, 54 | Interceptors: interList, 55 | BeforeServe: svc.BeforeServe, 56 | ServerOpts: serverOptions, 57 | RegisterAdditionalServers: svc.RegisterAdditionalServers, 58 | 59 | EnvVars: []string{ 60 | // Enable request validation 61 | gocsi.EnvVarSpecReqValidation + "=true", 62 | 63 | // Enable serial volume access 64 | gocsi.EnvVarSerialVolAccess + "=true", 65 | }, 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /provider/provider_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2025 Dell Inc, or its subsidiaries. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package provider 18 | 19 | import ( 20 | "bytes" 21 | "errors" 22 | "testing" 23 | 24 | csiutils "github.com/dell/csi-isilon/v2/csi-utils" 25 | "github.com/dell/gocsi" 26 | "github.com/sirupsen/logrus" 27 | "github.com/stretchr/testify/assert" 28 | ) 29 | 30 | // Mocking utility functions 31 | var ( 32 | mockGetLogger = func() *logrus.Entry { 33 | logger := logrus.New() 34 | logger.SetLevel(logrus.DebugLevel) 35 | var logBuffer bytes.Buffer 36 | logger.SetOutput(&logBuffer) 37 | return logrus.NewEntry(logger) 38 | } 39 | mockRemoveExistingCSISockFile = func() error { 40 | return errors.New("failed to remove existing CSI sock file") 41 | } 42 | ) 43 | 44 | func TestNew(t *testing.T) { 45 | // Inject the mock functions 46 | newTest := New() 47 | 48 | // Type assertion to access the fields of gocsi.StoragePlugin 49 | plugin, ok := newTest.(*gocsi.StoragePlugin) 50 | assert.True(t, ok, "newTest should be of type *gocsi.StoragePlugin") 51 | 52 | // Assertions 53 | assert.NotNil(t, plugin) 54 | assert.Equal(t, plugin.Controller, plugin.Identity) 55 | assert.Equal(t, plugin.Controller, plugin.Node) 56 | assert.Len(t, plugin.Interceptors, 2) 57 | assert.Len(t, plugin.ServerOpts, 1) 58 | assert.NotNil(t, plugin.BeforeServe) 59 | assert.NotNil(t, plugin.RegisterAdditionalServers) 60 | assert.Len(t, plugin.EnvVars, 2) 61 | 62 | // Test case: Removing existing CSI sock file succeeds 63 | csiutils.RemoveExistingCSISockFile = func() error { 64 | return errors.New("failed to remove existing CSI sock file") 65 | } 66 | 67 | newTest = New() 68 | plugin, ok = newTest.(*gocsi.StoragePlugin) 69 | assert.True(t, ok, "newTest should be of type *gocsi.StoragePlugin") 70 | 71 | // Assertions 72 | assert.NotNil(t, plugin) 73 | assert.Equal(t, plugin.Controller, plugin.Identity) 74 | assert.Equal(t, plugin.Controller, plugin.Node) 75 | assert.Len(t, plugin.Interceptors, 2) 76 | assert.Len(t, plugin.ServerOpts, 1) 77 | assert.NotNil(t, plugin.BeforeServe) 78 | assert.NotNil(t, plugin.RegisterAdditionalServers) 79 | assert.Len(t, plugin.EnvVars, 2) 80 | } 81 | -------------------------------------------------------------------------------- /samples/persistentvolumeclaim/pvc-from-pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvc-from-pvc 18 | namespace: default 19 | spec: 20 | accessModes: 21 | - ReadWriteMany 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 5Gi 26 | storageClassName: isilon 27 | dataSource: 28 | kind: PersistentVolumeClaim 29 | name: test-pvc 30 | apiGroup: "" 31 | -------------------------------------------------------------------------------- /samples/persistentvolumeclaim/pvc-from-snapshot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: PersistentVolumeClaim 16 | metadata: 17 | name: pvc-from-snapshot 18 | namespace: default 19 | spec: 20 | storageClassName: isilon 21 | dataSource: 22 | name: snapshot-of-test-pvc 23 | kind: VolumeSnapshot 24 | apiGroup: snapshot.storage.k8s.io 25 | accessModes: 26 | - ReadWriteMany 27 | resources: 28 | requests: 29 | storage: 5Gi 30 | -------------------------------------------------------------------------------- /samples/persistentvolumeclaim/pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: PersistentVolumeClaim 16 | metadata: 17 | name: test-pvc 18 | # Uncomment below 4 lines to set quota limit parameters 19 | # labels: 20 | # pvcSoftLimit: "10" 21 | # pvcAdvisoryLimit: "50" 22 | # pvcSoftGracePrd : "85400" 23 | spec: 24 | accessModes: 25 | - ReadWriteOnce 26 | resources: 27 | requests: 28 | storage: 5Gi 29 | storageClassName: isilon 30 | -------------------------------------------------------------------------------- /samples/pod/inline-volume.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: Pod 15 | apiVersion: v1 16 | metadata: 17 | name: my-csi-app-inline-volume 18 | spec: 19 | containers: 20 | - name: my-frontend 21 | image: busybox 22 | command: ["sleep", "100000"] 23 | volumeMounts: 24 | - mountPath: "/data" 25 | name: my-csi-volume 26 | volumes: 27 | - name: my-csi-volume 28 | csi: 29 | driver: csi-isilon.dellemc.com 30 | volumeAttributes: 31 | size: "2Gi" 32 | ClusterName: "cluster1" 33 | -------------------------------------------------------------------------------- /samples/pod/nginx.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: Pod 16 | metadata: 17 | name: nginx-pv-pod 18 | spec: 19 | containers: 20 | - name: task-pv-container 21 | image: nginx 22 | ports: 23 | - containerPort: 80 24 | name: "http-server" 25 | volumeMounts: 26 | - mountPath: "/usr/share/nginx/html" 27 | name: task-pv-storage 28 | volumes: 29 | - name: task-pv-storage 30 | persistentVolumeClaim: 31 | claimName: test-pvc 32 | -------------------------------------------------------------------------------- /samples/secret/empty-secret.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: Secret 16 | metadata: 17 | name: isilon-certs-0 18 | namespace: isilon 19 | type: Opaque 20 | data: 21 | cert-0: "" 22 | -------------------------------------------------------------------------------- /samples/secret/karavi-authorization-config.json: -------------------------------------------------------------------------------- 1 | [{"username":"-","password":"-","intendedEndpoint":"https://10.0.0.1:8080","endpoint":"https://localhost:9400","systemID":"myIsilonClusterName","skipCertificateValidation":true,"isDefault":true}] 2 | -------------------------------------------------------------------------------- /samples/volumesnapshot/snapshot-of-test-pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: snapshot.storage.k8s.io/v1 15 | kind: VolumeSnapshot 16 | metadata: 17 | name: snapshot-of-test-pvc 18 | namespace: default 19 | spec: 20 | volumeSnapshotClassName: isilon-snapclass 21 | source: 22 | persistentVolumeClaimName: test-pvc 23 | -------------------------------------------------------------------------------- /samples/volumesnapshotclass/isilon-volumesnapshotclass-v1.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | # For kubernetes version 20 (v1 snaps) 15 | apiVersion: snapshot.storage.k8s.io/v1 16 | kind: VolumeSnapshotClass 17 | metadata: 18 | name: isilon-snapclass 19 | driver: csi-isilon.dellemc.com 20 | 21 | # Configure what happens to a VolumeSnapshotContent when the VolumeSnapshot object 22 | # it is bound to is to be deleted 23 | # Allowed values: 24 | # Delete: the underlying storage snapshot will be deleted along with the VolumeSnapshotContent object. 25 | # Retain: both the underlying snapshot and VolumeSnapshotContent remain. 26 | deletionPolicy: Delete 27 | -------------------------------------------------------------------------------- /service/controllerNodeToArrayConnectivity.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | /* 4 | Copyright (c) 2022-2025 Dell Inc, or its subsidiaries. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "io" 23 | "net/http" 24 | "time" 25 | ) 26 | 27 | // timeout for making http requests 28 | var timeout = time.Second * 5 29 | 30 | var ( 31 | GetHTTPNewRequestWithContext = http.NewRequestWithContext 32 | GetIoReadAll = io.ReadAll 33 | getTimeNow = time.Now 34 | getPollingFrequency = func(ctx context.Context) int64 { 35 | return setPollingFrequency(ctx) 36 | } 37 | ) 38 | 39 | // queryStatus make API call to the specified url to retrieve connection status 40 | func (s *service) queryArrayStatus(ctx context.Context, url string) (bool, error) { 41 | ctx, log, _ := GetRunIDLog(ctx) 42 | defer func() { 43 | if err := recover(); err != nil { 44 | log.Println("panic occurred in queryStatus:", err) 45 | } 46 | }() 47 | log.Infof("Calling API %s with timeout %v", url, timeout) 48 | timeOutCtx, cancel := context.WithTimeout(ctx, timeout) 49 | defer cancel() 50 | 51 | req, err := GetHTTPNewRequestWithContext(timeOutCtx, "GET", url, nil) 52 | if err != nil { 53 | log.Errorf("failed to create request for API %s due to %s ", url, err.Error()) 54 | return false, err 55 | } 56 | req.Header.Add("Accept", "application/json") 57 | req.Header.Add("Content-Type", "application/json") 58 | log.Debugf("Making %s url request %+v", url, req) 59 | 60 | client := &http.Client{} 61 | resp, err := client.Do(req) 62 | log.Debugf("Received response %+v for url %s", resp, url) 63 | if err != nil { 64 | log.Errorf("failed to call API %s due to %s ", url, err.Error()) 65 | return false, err 66 | } 67 | defer func() { 68 | if err := resp.Body.Close(); err != nil { 69 | log.Printf("Error closing HTTP response: %s", err.Error()) 70 | } 71 | }() 72 | bodyBytes, err := GetIoReadAll(resp.Body) 73 | if err != nil { 74 | log.Errorf("failed to read API response due to %s ", err.Error()) 75 | return false, err 76 | } 77 | var statusResponse ArrayConnectivityStatus 78 | err = json.Unmarshal(bodyBytes, &statusResponse) 79 | if err != nil { 80 | log.Errorf("unable to unmarshal and determine connectivity due to %s ", err) 81 | return false, err 82 | } 83 | log.Infof("API Response received is %+v\n", statusResponse) 84 | // responseObject has last success and last attempt timestamp in Unix format 85 | timeDiff := statusResponse.LastAttempt - statusResponse.LastSuccess 86 | tolerance := getPollingFrequency(ctx) 87 | currTime := getTimeNow().Unix() 88 | // checking if the status response is stale and connectivity test is still running 89 | // since nodeProbe is run at frequency tolerance/2, ideally below check should never be true 90 | if (currTime - statusResponse.LastAttempt) > tolerance*2 { 91 | log.Errorf("seems like connectivity test is not being run, current time is %d and last run was at %d", currTime, statusResponse.LastAttempt) 92 | // considering connectivity is broken 93 | return false, nil 94 | } 95 | log.Debugf("last connectivity was %d sec back, tolerance is %d sec", timeDiff, tolerance) 96 | // give 2s leeway for tolerance check 97 | if timeDiff <= tolerance+2 { 98 | return true, nil 99 | } 100 | return false, nil 101 | } 102 | -------------------------------------------------------------------------------- /service/features/controller_expand_volume.feature: -------------------------------------------------------------------------------- 1 | Feature: Isilon CSI interface 2 | As a consumer of the CSI interface 3 | I want to test volume expansion service methods 4 | So that they are known to work 5 | 6 | @expandVolume 7 | @v1.1.0 8 | Scenario: Controller Expand volume good scenario with Quota enabled 9 | Given a Isilon service 10 | And I enable quota 11 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System" "108589934592" 12 | Then a valid ControllerExpandVolumeResponse is returned 13 | 14 | Scenario: Controller Expand volume good scenario with Quota enabled and non-existing volume 15 | Given a Isilon service 16 | And I enable quota 17 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System=_=_=cluster1" "108589934592" 18 | Then a valid ControllerExpandVolumeResponse is returned 19 | 20 | Scenario: Controller Expand volume negative scenario with Quota enabled 21 | Given a Isilon service 22 | And I enable quota 23 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System=_=_=cluster2" "108589934592" 24 | Then the error contains "failed to get cluster config details for clusterName: 'cluster2'" 25 | 26 | Scenario: Controller Expand volume good scenario with Quota disabled 27 | Given a Isilon service 28 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System" "108589934592" 29 | Then a valid ControllerExpandVolumeResponse is returned 30 | 31 | Scenario: Controller Expand volume idempotent scenario with Quota enabled 32 | Given a Isilon service 33 | And I enable quota 34 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System" "589934592" 35 | Then a valid ControllerExpandVolumeResponse is returned 36 | 37 | Scenario Outline: Controller Expand volume with negative arguments and Quota enabled 38 | Given a Isilon service 39 | And I enable quota 40 | When I call ControllerExpandVolume 41 | Then a valid ControllerExpandVolumeResponse is returned 42 | 43 | Examples: 44 | | volumeID | requiredBytes | 45 | | "volume1=_=_=557=_=_=System" | "-108589934592" | 46 | 47 | Scenario Outline: Controller Expand volume with induced errors and Quota enabled 48 | Given a Isilon service 49 | And I enable quota 50 | When I induce error 51 | And I call ControllerExpandVolume "volume1=_=_=557=_=_=System" "108589934592" 52 | Then the error contains 53 | 54 | Examples: 55 | | induced | errormsg | 56 | | "UpdateQuotaError" | "failed to update quota" | 57 | 58 | Scenario: Calling functions with autoProbe failed 59 | Given a Isilon service 60 | And I induce error "autoProbeFailed" 61 | When I call ControllerExpandVolume "volume1=_=_=557=_=_=System" "108589934592" 62 | Then the error contains "auto probe is not enabled" 63 | 64 | Scenario: Calling functions with invalid volume id 65 | Given a Isilon service 66 | When I call ControllerExpandVolume "volume1=_=_=557" "108589934592" 67 | Then the error contains "volume ID @@ cannot be split into tokens" 68 | -------------------------------------------------------------------------------- /service/features/csi_extension.feature: -------------------------------------------------------------------------------- 1 | Feature: Isilon CSI interface 2 | As a consumer of the CSI interface 3 | I want to test service methods 4 | So that they are known to work 5 | 6 | @podmon 7 | @v1.0.0 8 | Scenario: Call ValidateConnectivity 9 | Given a Isilon service 10 | When I call Probe 11 | And I call CreateVolume "volume1" 12 | And a valid CreateVolumeResponse is returned 13 | And I call ValidateConnectivity 14 | Then the error contains "none" 15 | 16 | Scenario: Call ValidateConnectivity with invalid volID 17 | Given a Isilon service 18 | When I call Probe 19 | And I call CreateVolume "volume1" 20 | And I induce error "invalid-volumeId" 21 | And I call ValidateConnectivity 22 | Then the error contains "none" 23 | 24 | Scenario: Call ValidateConnectivity with invalid NodeID 25 | Given a Isilon service 26 | When I call Probe 27 | And I call CreateVolume "volume1" 28 | And I induce error "invalid-nodeId" 29 | And I call ValidateConnectivity 30 | Then the error contains "failed to parse node ID" 31 | 32 | Scenario: Call ValidateConnectivity with no Node 33 | Given a Isilon service 34 | When I call CreateVolume "volume1" 35 | And I induce error "no-nodeId" 36 | And I call ValidateConnectivity 37 | Then the error contains "the NodeID is a required field" 38 | 39 | Scenario: Call ValidateConnectivity with no Volume no Node 40 | Given a Isilon service 41 | And I induce error "no-volume-no-nodeId" 42 | And I call ValidateConnectivity 43 | Then the error contains "ValidateVolumeHostConnectivity is implemented" 44 | 45 | Scenario: Call Validate Url Status 46 | Given a Isilon service 47 | And I call QueryArrayStatus "36443" 48 | Then the error contains "none" 49 | 50 | Scenario: Call Modify LastAttempt with delay 51 | Given a Isilon service 52 | And I induce error "ModifyLastAttempt" 53 | And I call QueryArrayStatus "36443" 54 | Then the error contains "none" -------------------------------------------------------------------------------- /service/features/isiService.feature: -------------------------------------------------------------------------------- 1 | Feature: Isilon CSI interface 2 | As a consumer of the CSI interface 3 | I want to test service methods 4 | So that they are known to work 5 | 6 | Scenario: Calling create quota in isiService with negative sizeInBytes 7 | Given a Isilon service 8 | When I call CreateQuota in isiService with 9 | Then the error contains "none" 10 | Examples: 11 | | softLimit | advisoryLimit | softgraceprd | sizeInBytes 12 | | "0" | "30" | "0" | -1 13 | | "40" | "0" | "85600" | 53687091 14 | | "60" | "80" | "85600" | 53687091 15 | | "110" | "80" | "85600" | 53687091 16 | | "-1" | "-1" | "85600" | 53687091 17 | | "ab" | "-1" | "85600" | 53687091 18 | 19 | Scenario: Calling get export with no result 20 | Given a Isilon service 21 | When I induce error "GetExportInternalError" 22 | And I call get export related functions in isiService 23 | Then the error contains "EOF" 24 | 25 | Scenario Outline: GetSnapshotNameFromIsiPath with params 26 | Given a Isilon service 27 | And I call GetSnapshotNameFromIsiPath with 28 | Then the error contains 29 | Examples: 30 | | isipath | errormsg | 31 | | "" | "invalid snapshot isilon path" | 32 | | "/ifs/.snapshot" | "invalid snapshot isilon path" | 33 | | "/ifs/.snapshot/data/csiislon" | "none" | 34 | 35 | Scenario: GetSnapshotIsiPathComponents 36 | Given a Isilon service 37 | And I call GetSnapshotIsiPathComponents 38 | Then the error contains "none" 39 | 40 | Scenario: GetSubDirectoryCount 41 | Given a Isilon service 42 | And I call GetSubDirectoryCount 43 | Then the error contains "none" 44 | 45 | Scenario: DeleteSnapshot case 46 | Given a Isilon service 47 | And I call DeleteSnapshotIsiService 48 | Then the error contains "none" 49 | -------------------------------------------------------------------------------- /service/mock/cluster/get_cluster_config.txt: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "devices": [ 4 | { 5 | "devid": 1, 6 | "guid": "000e1ea5825065e0e65c231d37b8ab381ab7", 7 | "is_up": true, 8 | "lnn": 1 9 | }, 10 | { 11 | "devid": 2, 12 | "guid": "000e1ea577400ee7e65c401ce161d195da97", 13 | "is_up": true, 14 | "lnn": 2 15 | }, 16 | { 17 | "devid": 3, 18 | "guid": "000e1ea577302ce6e65c4a1fe30e4d5cc72a", 19 | "is_up": true, 20 | "lnn": 3 21 | } 22 | ], 23 | "encoding": "utf-8", 24 | "guid": "000e1ea582501ce1e65c8e123920ccb186fe", 25 | "has_quorum": true, 26 | "is_compliance": false, 27 | "is_virtual": false, 28 | "is_vonefs": false, 29 | "join_mode": "Manual", 30 | "local_devid": 1, 31 | "local_lnn": 1, 32 | "local_serial": "SX410-301543-0031", 33 | "name": "PIE-IsilonX", 34 | "onefs_version": { 35 | "build": "B_8_2_0_0_009(RELEASE)", 36 | "copyright": "Copyright (c) 2001-2016 EMC Corporation. All Rights Reserved.", 37 | "reldate": 1200019, 38 | "release": "v8.2.0.0", 39 | "revision": "577024045854228489", 40 | "type": "Isilon OneFS", 41 | "version": "Isilon OneFS v8.2.0.0 B_8_2_0_0_009(RELEASE): 0x802005000000009:Mon May 6 17:10:51 PDT 2019 root@sea-build11-01:/b/mnt/obj/b/mnt/src/amd64.amd64/sys/IQ.amd64.release FreeBSD clang version 3.9.1 (tags/RELEASE_391/final 289601) (based on LLVM 3.9.1)" 42 | }, 43 | "timezone": { 44 | "abbreviation": "EDT", 45 | "custom": "", 46 | "name": "Eastern Time Zone", 47 | "path": "America/New_York" 48 | }, 49 | "upgrade_type": null 50 | } -------------------------------------------------------------------------------- /service/mock/export/create_export_557.txt: -------------------------------------------------------------------------------- 1 | { 2 | "id": 557 3 | } -------------------------------------------------------------------------------- /service/mock/export/export_not_found_by_id.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_NOT_FOUND", 5 | "field": "id", 6 | "message": "Export id 9999999 does not exist" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /service/mock/export/get_export_557.txt: -------------------------------------------------------------------------------- 1 | { 2 | "exports": [ 3 | { 4 | "all_dirs": false, 5 | "block_size": 8192, 6 | "can_set_time": true, 7 | "case_insensitive": false, 8 | "case_preserving": true, 9 | "chown_restricted": false, 10 | "clients": [], 11 | "commit_asynchronous": false, 12 | "conflicting_paths": [], 13 | "description": "CSI_QUOTA_ID:AABpAQEAAAAAAAAAAAAAQA0AAAAAAAAA", 14 | "directory_transfer_size": 131072, 15 | "encoding": "DEFAULT", 16 | "id": 557, 17 | "link_max": 32767, 18 | "map_failure": { 19 | "enabled": false, 20 | "primary_group": {}, 21 | "secondary_groups": [], 22 | "user": { 23 | "id": "USER:nobody" 24 | } 25 | }, 26 | "map_full": true, 27 | "map_lookup_uid": false, 28 | "map_non_root": { 29 | "enabled": false, 30 | "primary_group": {}, 31 | "secondary_groups": [], 32 | "user": { 33 | "id": "USER:nobody" 34 | } 35 | }, 36 | "map_retry": true, 37 | "map_root": { 38 | "enabled": true, 39 | "primary_group": {}, 40 | "secondary_groups": [], 41 | "user": { 42 | "id": "USER:nobody" 43 | } 44 | }, 45 | "max_file_size": 9223372036854775807, 46 | "name_max_size": 255, 47 | "no_truncate": false, 48 | "paths": [ 49 | "/ifs/data/csi-isilon/volume1" 50 | ], 51 | "read_only": false, 52 | "read_only_clients": [], 53 | "read_transfer_max_size": 1048576, 54 | "read_transfer_multiple": 512, 55 | "read_transfer_size": 131072, 56 | "read_write_clients": [], 57 | "readdirplus": true, 58 | "readdirplus_prefetch": 10, 59 | "return_32bit_file_ids": false, 60 | "root_clients": [], 61 | "security_flavors": [ 62 | "unix" 63 | ], 64 | "setattr_asynchronous": false, 65 | "snapshot": "-", 66 | "symlinks": true, 67 | "time_delta": 1.000000000000000e-09, 68 | "unresolved_clients": [], 69 | "write_datasync_action": "DATASYNC", 70 | "write_datasync_reply": "DATASYNC", 71 | "write_filesync_action": "FILESYNC", 72 | "write_filesync_reply": "FILESYNC", 73 | "write_transfer_max_size": 1048576, 74 | "write_transfer_multiple": 512, 75 | "write_transfer_size": 524288, 76 | "write_unstable_action": "UNSTABLE", 77 | "write_unstable_reply": "UNSTABLE", 78 | "zone": "System" 79 | } 80 | ] 81 | } -------------------------------------------------------------------------------- /service/mock/export/get_export_not_found.txt: -------------------------------------------------------------------------------- 1 | { 2 | "digest": "a88ac47374d79dcbf43681a73c90bd29", 3 | "exports": [], 4 | "resume": null, 5 | "total": 0 6 | } -------------------------------------------------------------------------------- /service/mock/export/get_export_snapVol3.txt: -------------------------------------------------------------------------------- 1 | { 2 | "exports": [ 3 | { 4 | "all_dirs": false, 5 | "block_size": 8192, 6 | "can_set_time": true, 7 | "case_insensitive": false, 8 | "case_preserving": true, 9 | "chown_restricted": false, 10 | "clients": [], 11 | "commit_asynchronous": false, 12 | "conflicting_paths": [], 13 | "description": "CSI_QUOTA_ID:AABpAQEAAAAAAAAAAAAAQA0AAAAAAAAA", 14 | "directory_transfer_size": 131072, 15 | "encoding": "DEFAULT", 16 | "id": 557, 17 | "link_max": 32767, 18 | "map_failure": { 19 | "enabled": false, 20 | "primary_group": {}, 21 | "secondary_groups": [], 22 | "user": { 23 | "id": "USER:nobody" 24 | } 25 | }, 26 | "map_full": true, 27 | "map_lookup_uid": false, 28 | "map_non_root": { 29 | "enabled": false, 30 | "primary_group": {}, 31 | "secondary_groups": [], 32 | "user": { 33 | "id": "USER:nobody" 34 | } 35 | }, 36 | "map_retry": true, 37 | "map_root": { 38 | "enabled": true, 39 | "primary_group": {}, 40 | "secondary_groups": [], 41 | "user": { 42 | "id": "USER:nobody" 43 | } 44 | }, 45 | "max_file_size": 9223372036854775807, 46 | "name_max_size": 255, 47 | "no_truncate": false, 48 | "paths": [ 49 | "/ifs/.snapshot/k8s-12345678/volSnap2" 50 | ], 51 | "read_only": false, 52 | "read_only_clients": [], 53 | "read_transfer_max_size": 1048576, 54 | "read_transfer_multiple": 512, 55 | "read_transfer_size": 131072, 56 | "read_write_clients": [], 57 | "readdirplus": true, 58 | "readdirplus_prefetch": 10, 59 | "return_32bit_file_ids": false, 60 | "root_clients": [], 61 | "security_flavors": [ 62 | "unix" 63 | ], 64 | "setattr_asynchronous": false, 65 | "snapshot": "-", 66 | "symlinks": true, 67 | "time_delta": 1.000000000000000e-09, 68 | "unresolved_clients": [], 69 | "write_datasync_action": "DATASYNC", 70 | "write_datasync_reply": "DATASYNC", 71 | "write_filesync_action": "FILESYNC", 72 | "write_filesync_reply": "FILESYNC", 73 | "write_transfer_max_size": 1048576, 74 | "write_transfer_multiple": 512, 75 | "write_transfer_size": 524288, 76 | "write_unstable_action": "UNSTABLE", 77 | "write_unstable_reply": "UNSTABLE", 78 | "zone": "System" 79 | } 80 | ] 81 | } -------------------------------------------------------------------------------- /service/mock/export/get_exports_snapVol2.txt: -------------------------------------------------------------------------------- 1 | { 2 | "exports": [ 3 | { 4 | "all_dirs": false, 5 | "block_size": 8192, 6 | "can_set_time": true, 7 | "case_insensitive": false, 8 | "case_preserving": true, 9 | "chown_restricted": false, 10 | "clients": [], 11 | "commit_asynchronous": false, 12 | "conflicting_paths": [], 13 | "description": "CSI_QUOTA_ID:AABpAQEAAAAAAAAAAAAAQA0AAAAAAARR", 14 | "directory_transfer_size": 131072, 15 | "encoding": "DEFAULT", 16 | "id": 0, 17 | "link_max": 32767, 18 | "map_failure": { 19 | "enabled": false, 20 | "primary_group": {}, 21 | "secondary_groups": [], 22 | "user": { 23 | "id": "USER:nobody" 24 | } 25 | }, 26 | "map_full": true, 27 | "map_lookup_uid": false, 28 | "map_non_root": { 29 | "enabled": false, 30 | "primary_group": {}, 31 | "secondary_groups": [], 32 | "user": { 33 | "id": "USER:nobody" 34 | } 35 | }, 36 | "map_retry": true, 37 | "map_root": { 38 | "enabled": true, 39 | "primary_group": {}, 40 | "secondary_groups": [], 41 | "user": { 42 | "id": "USER:nobody" 43 | } 44 | }, 45 | "max_file_size": 9223372036854775807, 46 | "name_max_size": 255, 47 | "no_truncate": false, 48 | "paths": [ 49 | "/ifs/.snapshot/volSnap2" 50 | ], 51 | "read_only": false, 52 | "read_only_clients": [], 53 | "read_transfer_max_size": 1048576, 54 | "read_transfer_multiple": 512, 55 | "read_transfer_size": 131072, 56 | "read_write_clients": [], 57 | "readdirplus": true, 58 | "readdirplus_prefetch": 10, 59 | "return_32bit_file_ids": false, 60 | "root_clients": [], 61 | "security_flavors": [ 62 | "unix" 63 | ], 64 | "setattr_asynchronous": false, 65 | "snapshot": "-", 66 | "symlinks": true, 67 | "time_delta": 1.000000000000000e-09, 68 | "unresolved_clients": [], 69 | "write_datasync_action": "DATASYNC", 70 | "write_datasync_reply": "DATASYNC", 71 | "write_filesync_action": "FILESYNC", 72 | "write_filesync_reply": "FILESYNC", 73 | "write_transfer_max_size": 1048576, 74 | "write_transfer_multiple": 512, 75 | "write_transfer_size": 524288, 76 | "write_unstable_action": "UNSTABLE", 77 | "write_unstable_reply": "UNSTABLE", 78 | "zone": "System" 79 | } 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /service/mock/export/get_exports_with_invalid_resume.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_BAD_REQUEST", 5 | "message": "Invalid resume token" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/jobs/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "id" : "20" 3 | } -------------------------------------------------------------------------------- /service/mock/jobs/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobs" : [], 3 | "resume" : null, 4 | "total" : 0 5 | } 6 | -------------------------------------------------------------------------------- /service/mock/loglevel/logBackup.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | -------------------------------------------------------------------------------- /service/mock/loglevel/logConfig.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | CSI_LOG_LEVEL: "Debug" 15 | -------------------------------------------------------------------------------- /service/mock/loglevel/logConfigError.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | CSI_LOG_LEVEL: "xyz" 15 | -------------------------------------------------------------------------------- /service/mock/loglevel/logLevelInfo.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | CSI_LOG_LEVEL: "INFO" 15 | -------------------------------------------------------------------------------- /service/mock/policy/empty.txt: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "policies" : 4 | [ 5 | 6 | { 7 | "failover_failback_state" : "writes_disabled", 8 | "id" : "9c9b581c60b4314b21e339796ea66ac7", 9 | "last_job_state" : "finished", 10 | "last_source_coordinator_ip" : "192.168.111.20", 11 | "last_update_from_source" : 1644930873, 12 | "legacy_policy" : false, 13 | "name" : "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 14 | "source_cluster_guid" : "0050568876308e650b62651a8b25f5982d90", 15 | "source_host" : "max", 16 | "target_path" : "/ifs/data/csi/csi-prov-test-19743d82-192-168-111-25-Five_Minutes" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /service/mock/policy/get_policies.txt: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "accelerated_failback": false, 5 | "action": "sync", 6 | "bandwidth_reservation": null, 7 | "changelist": false, 8 | "check_integrity": true, 9 | "cloud_deep_copy": "deny", 10 | "conflicted": false, 11 | "database_mirrored": false, 12 | "delete_quotas": true, 13 | "description": "", 14 | "disable_file_split": false, 15 | "disable_fofb": false, 16 | "disable_quota_tmp_dir": false, 17 | "disable_stf": false, 18 | "enable_hash_tmpdir": false, 19 | "enabled": true, 20 | "encrypted": false, 21 | "encryption_cipher_list": "", 22 | "expected_dataloss": false, 23 | "file_matching_pattern": {}, 24 | "force_interface": false, 25 | "has_sync_state": false, 26 | "id": "6e3e43821248d345853c52a04199a163", 27 | "job_delay": 300, 28 | "last_job_state": "failed", 29 | "last_started": 1645532377, 30 | "last_success": null, 31 | "linked_service_policies": [], 32 | "log_level": "notice", 33 | "log_removed_files": false, 34 | "name": "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 35 | "next_run": 1645533635, 36 | "ocsp_address": "", 37 | "ocsp_issuer_certificate_id": "", 38 | "password_set": false, 39 | "priority": 0, 40 | "report_max_age": 31536000, 41 | "report_max_count": 2000, 42 | "restrict_target_network": false, 43 | "rpo_alert": null, 44 | "schedule": "when-source-modified", 45 | "service_policy": false, 46 | "skip_when_source_unmodified": false, 47 | "snapshot_sync_existing": false, 48 | "snapshot_sync_pattern": "*", 49 | "source_certificate_id": "", 50 | "source_domain_marked": false, 51 | "source_exclude_directories": [], 52 | "source_include_directories": [], 53 | "source_network": null, 54 | "source_root_path": "/ifs/data/new/csi-prov-test-19743d82-192.168.111.25-Five_Minutes", 55 | "source_snapshot_archive": false, 56 | "source_snapshot_expiration": 0, 57 | "source_snapshot_pattern": "", 58 | "target_certificate_id": "", 59 | "target_compare_initial_sync": false, 60 | "target_detect_modifications": true, 61 | "target_host": "192.168.111.20", 62 | "target_path": "/ifs/data/new/csi-prov-test-19743d82-192.168.111.25-Five_Minutes", 63 | "target_snapshot_alias": "SIQ-%{SrcCluster}-%{PolicyName}-latest", 64 | "target_snapshot_archive": false, 65 | "target_snapshot_expiration": 0, 66 | "target_snapshot_pattern": "SIQ-%{SrcCluster}-%{PolicyName}-%Y-%m-%d_%H-%M-%S", 67 | "workers_per_node": 3 68 | } 69 | ] 70 | } -------------------------------------------------------------------------------- /service/mock/policy/get_policies2.txt: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "accelerated_failback": false, 5 | "action": "sync", 6 | "bandwidth_reservation": null, 7 | "changelist": false, 8 | "check_integrity": true, 9 | "cloud_deep_copy": "deny", 10 | "conflicted": false, 11 | "database_mirrored": false, 12 | "delete_quotas": true, 13 | "description": "", 14 | "disable_file_split": false, 15 | "disable_fofb": false, 16 | "disable_quota_tmp_dir": false, 17 | "disable_stf": false, 18 | "enable_hash_tmpdir": false, 19 | "enabled": false, 20 | "encrypted": false, 21 | "encryption_cipher_list": "", 22 | "expected_dataloss": false, 23 | "file_matching_pattern": {}, 24 | "force_interface": false, 25 | "has_sync_state": false, 26 | "id": "6e3e43821248d345853c52a04199a163", 27 | "job_delay": 300, 28 | "last_job_state": "failed", 29 | "last_started": 1645532377, 30 | "last_success": null, 31 | "linked_service_policies": [], 32 | "log_level": "notice", 33 | "log_removed_files": false, 34 | "name": "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 35 | "next_run": 1645533635, 36 | "ocsp_address": "", 37 | "ocsp_issuer_certificate_id": "", 38 | "password_set": false, 39 | "priority": 0, 40 | "report_max_age": 31536000, 41 | "report_max_count": 2000, 42 | "restrict_target_network": false, 43 | "rpo_alert": null, 44 | "schedule": "when-source-modified", 45 | "service_policy": false, 46 | "skip_when_source_unmodified": false, 47 | "snapshot_sync_existing": false, 48 | "snapshot_sync_pattern": "*", 49 | "source_certificate_id": "", 50 | "source_domain_marked": false, 51 | "source_exclude_directories": [], 52 | "source_include_directories": [], 53 | "source_network": null, 54 | "source_root_path": "/ifs/data/new/csi-prov-test-19743d82-192.168.111.25-Five_Minutes", 55 | "source_snapshot_archive": false, 56 | "source_snapshot_expiration": 0, 57 | "source_snapshot_pattern": "", 58 | "target_certificate_id": "", 59 | "target_compare_initial_sync": false, 60 | "target_detect_modifications": true, 61 | "target_host": "192.168.111.20", 62 | "target_path": "/ifs/data/new/csi-prov-test-19743d82-192.168.111.25-Five_Minutes", 63 | "target_snapshot_alias": "SIQ-%{SrcCluster}-%{PolicyName}-latest", 64 | "target_snapshot_archive": false, 65 | "target_snapshot_expiration": 0, 66 | "target_snapshot_pattern": "SIQ-%{SrcCluster}-%{PolicyName}-%Y-%m-%d_%H-%M-%S", 67 | "workers_per_node": 3 68 | } 69 | ] 70 | } -------------------------------------------------------------------------------- /service/mock/policy/get_policies_sync.txt: -------------------------------------------------------------------------------- 1 | { 2 | "policies": [ 3 | { 4 | "enabled": true, 5 | "name": "vgname", 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/policy/get_target_policies.txt: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "policies" : 4 | [ 5 | 6 | { 7 | "failover_failback_state" : "writes_disabled", 8 | "id" : "9c9b581c60b4314b21e339796ea66ac7", 9 | "last_job_state" : "finished", 10 | "last_source_coordinator_ip" : "192.168.111.20", 11 | "last_update_from_source" : 1644930873, 12 | "legacy_policy" : false, 13 | "name" : "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 14 | "source_cluster_guid" : "0050568876308e650b62651a8b25f5982d90", 15 | "source_host" : "max", 16 | "target_path" : "/ifs/data/csi/csi-prov-test-19743d82-192-168-111-25-Five_Minutes" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /service/mock/policy/get_target_policies2.txt: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "policies" : 4 | [ 5 | 6 | { 7 | "failover_failback_state" : "writes_enabled", 8 | "id" : "9c9b581c60b4314b21e339796ea66ac7", 9 | "last_job_state" : "finished", 10 | "last_source_coordinator_ip" : "192.168.111.20", 11 | "last_update_from_source" : 1644930873, 12 | "legacy_policy" : false, 13 | "name" : "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 14 | "source_cluster_guid" : "0050568876308e650b62651a8b25f5982d90", 15 | "source_host" : "max", 16 | "target_path" : "/ifs/data/csi/csi-prov-test-19743d82-192-168-111-25-Five_Minutes" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /service/mock/policy/tp_failed.txt: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "policies" : 4 | [ 5 | 6 | { 7 | "failover_failback_state" : "writes_disabled", 8 | "id" : "9c9b581c60b4314b21e339796ea66ac7", 9 | "last_job_state" : "failed", 10 | "last_source_coordinator_ip" : "192.168.111.20", 11 | "last_update_from_source" : 1644930873, 12 | "legacy_policy" : false, 13 | "name" : "csi-prov-test-19743d82-192-168-111-25-Five_Minutes", 14 | "source_cluster_guid" : "0050568876308e650b62651a8b25f5982d90", 15 | "source_host" : "max", 16 | "target_path" : "/ifs/data/csi/csi-prov-test-19743d82-192-168-111-25-Five_Minutes" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /service/mock/quota/create_quota.txt: -------------------------------------------------------------------------------- 1 | { 2 | "id": "AABpAQEAAAAAAAAAAAAAQA0AAAAAAAAA" 3 | } -------------------------------------------------------------------------------- /service/mock/quota/get_quota_by_id.txt: -------------------------------------------------------------------------------- 1 | { 2 | "quotas": [ 3 | { 4 | "container": true, 5 | "enforced": true, 6 | "id": "WACnAAEAAAAAAAAAAAAAQBUPAAAAAAAA", 7 | "include_snapshots": false, 8 | "linked": false, 9 | "notifications": "default", 10 | "path": "/ifs/data/csi/Hui/k8s-37fae6e3fa", 11 | "persona": null, 12 | "ready": true, 13 | "thresholds": { 14 | "advisory": null, 15 | "advisory_exceeded": false, 16 | "advisory_last_exceeded": null, 17 | "hard": 8589934592, 18 | "hard_exceeded": false, 19 | "hard_last_exceeded": null, 20 | "percent_advisory": null, 21 | "percent_soft": null, 22 | "soft": null, 23 | "soft_exceeded": false, 24 | "soft_grace": null, 25 | "soft_last_exceeded": null 26 | }, 27 | "thresholds_include_overhead": false, 28 | "type": "directory", 29 | "usage": { 30 | "inodes": 1, 31 | "logical": 0, 32 | "physical": 2048 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /service/mock/quota/get_quota_by_id_4gb.txt: -------------------------------------------------------------------------------- 1 | { 2 | "quotas": [ 3 | { 4 | "container": true, 5 | "enforced": true, 6 | "id": "WACnAAEAAAAAAAAAAAAAQBUPAAAAAAAA", 7 | "include_snapshots": false, 8 | "linked": false, 9 | "notifications": "default", 10 | "path": "/ifs/data/csi/Hui/k8s-37fae6e3fa", 11 | "persona": null, 12 | "ready": true, 13 | "thresholds": { 14 | "advisory": null, 15 | "advisory_exceeded": false, 16 | "advisory_last_exceeded": null, 17 | "hard": 4294967296, 18 | "hard_exceeded": false, 19 | "hard_last_exceeded": null, 20 | "percent_advisory": null, 21 | "percent_soft": null, 22 | "soft": null, 23 | "soft_exceeded": false, 24 | "soft_grace": null, 25 | "soft_last_exceeded": null 26 | }, 27 | "thresholds_include_overhead": false, 28 | "type": "directory", 29 | "usage": { 30 | "inodes": 1, 31 | "logical": 0, 32 | "physical": 2048 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /service/mock/quota/get_quota_by_id_8gb.txt: -------------------------------------------------------------------------------- 1 | { 2 | "quotas": [ 3 | { 4 | "container": true, 5 | "enforced": true, 6 | "id": "WACnAAEAAAAAAAAAAAAAQBUPAAAAAAAA", 7 | "include_snapshots": false, 8 | "linked": false, 9 | "notifications": "default", 10 | "path": "/ifs/data/csi/Hui/k8s-37fae6e3fa", 11 | "persona": null, 12 | "ready": true, 13 | "thresholds": { 14 | "advisory": null, 15 | "advisory_exceeded": false, 16 | "advisory_last_exceeded": null, 17 | "hard": 8589934592, 18 | "hard_exceeded": false, 19 | "hard_last_exceeded": null, 20 | "percent_advisory": null, 21 | "percent_soft": null, 22 | "soft": null, 23 | "soft_exceeded": false, 24 | "soft_grace": null, 25 | "soft_last_exceeded": null 26 | }, 27 | "thresholds_include_overhead": false, 28 | "type": "directory", 29 | "usage": { 30 | "inodes": 1, 31 | "logical": 0, 32 | "physical": 2048 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /service/mock/quota/get_quota_license.txt: -------------------------------------------------------------------------------- 1 | { 2 | "days_to_expiry": 71, 3 | "expiration": "2019-10-14", 4 | "expired_alert": false, 5 | "expiring_alert": false, 6 | "id": "SMARTQUOTAS", 7 | "name": "SMARTQUOTAS", 8 | "status": "Evaluation", 9 | "tiers": [ 10 | { 11 | "licensed_node_count": 3, 12 | "tier": "NONINF", 13 | "used_node_count": 3 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /service/mock/quota/invalid_quota.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_NOT_FOUND", 5 | "message": "quota not found:" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/quota/quota_not_found.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_NOT_FOUND", 5 | "message": "Failed to fetch quota domain record: No such file or directory" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/secret/secret.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | isilonClusters: 15 | - clusterName: "cluster1" 16 | username: "blah" 17 | password: "blah" 18 | endpoint: "127.0.0.1" 19 | isDefault: true 20 | -------------------------------------------------------------------------------- /service/mock/snapshot/create_snapshot.txt: -------------------------------------------------------------------------------- 1 | { 2 | "created" : 1567491928, 3 | "id" : 34, 4 | "name" : "create_Snapshot_name", 5 | "path" : "/ifs/data/csi-isilon/volume2", 6 | "size" : 4096, 7 | "state" : "active" 8 | } 9 | -------------------------------------------------------------------------------- /service/mock/snapshot/get_existent_compatible_snapshot.txt: -------------------------------------------------------------------------------- 1 | { 2 | "snapshots" : 3 | [ 4 | 5 | { 6 | "created" : 1567061367, 7 | "expires" : null, 8 | "has_locks" : false, 9 | "id" : 3, 10 | "name" : "existent_comp_snapshot_name", 11 | "path" : "/ifs/data/csi-isilon/volume2", 12 | "pct_filesystem" : 8.106093574156148e-09, 13 | "pct_reserve" : 0.0, 14 | "schedule" : null, 15 | "shadow_bytes" : 0, 16 | "size" : 8192, 17 | "state" : "active", 18 | "target_id" : null, 19 | "target_name" : null 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /service/mock/snapshot/get_existent_snapshot_2.txt: -------------------------------------------------------------------------------- 1 | { 2 | "snapshots" : 3 | [ 4 | 5 | { 6 | "created" : 1567061367, 7 | "expires" : null, 8 | "has_locks" : false, 9 | "id" : 2, 10 | "name" : "existent_snapshot_name", 11 | "path" : "/ifs/data/yian/nfs_1", 12 | "pct_filesystem" : 8.106093574156148e-09, 13 | "pct_reserve" : 0.0, 14 | "schedule" : null, 15 | "shadow_bytes" : 0, 16 | "size" : 8192, 17 | "state" : "active", 18 | "target_id" : null, 19 | "target_name" : null 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /service/mock/snapshot/get_existent_snapshot_4.txt: -------------------------------------------------------------------------------- 1 | { 2 | "snapshots" : 3 | [ 4 | { 5 | "created" : 1567061367, 6 | "expires" : null, 7 | "has_locks" : false, 8 | "id" : 4, 9 | "name" : "existent_snapshot_name_4", 10 | "path" : "ifs/data/csi-isilon/childZone/nfs_4", 11 | "pct_filesystem" : 8.106093574156148e-09, 12 | "pct_reserve" : 0.0, 13 | "schedule" : null, 14 | "shadow_bytes" : 0, 15 | "size" : 8192, 16 | "state" : "active", 17 | "target_id" : null, 18 | "target_name" : null 19 | } 20 | 21 | ] 22 | } -------------------------------------------------------------------------------- /service/mock/snapshot/get_non_existent_snapshot.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_NOT_FOUND", 5 | "message": "new_snapshot_name snapshot not found" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/snapshot/get_snapshot_size.txt: -------------------------------------------------------------------------------- 1 | {"children":[{ 2 | "name" : "DELLEMC_UnityFileSra_v6.0.1.85.tar", 3 | "size" : 665332736 4 | } 5 | ,{ 6 | "name" : "t1.txt", 7 | "size" : 138 8 | } 9 | ,{ 10 | "name" : "dir1", 11 | "size" : 24 12 | } 13 | ,{ 14 | "name" : "t2.txt", 15 | "size" : 161 16 | } 17 | ]} 18 | -------------------------------------------------------------------------------- /service/mock/snapshot/get_zone_by_name.txt: -------------------------------------------------------------------------------- 1 | { 2 | "zones" : 3 | [ 4 | { 5 | "alternate_system_provider" : "lsa-file-provider:MinimumRequired", 6 | "auth_providers" : [ "lsa-local-provider:zone2" ], 7 | "cache_entry_expiry" : 14400, 8 | "groupnet" : "groupnet0", 9 | "home_directory_umask" : 63, 10 | "id" : "zone2", 11 | "ifs_restricted" : [], 12 | "map_untrusted" : "", 13 | "name" : "System", 14 | "negative_cache_entry_expiry" : 60, 15 | "netbios_name" : "", 16 | "path" : "/ifs", 17 | "skeleton_directory" : "/usr/share/skel", 18 | "system" : false, 19 | "system_provider" : "lsa-file-provider:System", 20 | "user_mapping_rules" : [], 21 | "zone_id" : 2 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /service/mock/statistics/IO_not_inprogress.txt: -------------------------------------------------------------------------------- 1 | { 2 | "client": [ 3 | { 4 | "class": "other", 5 | "in": 7.800000190734863, 6 | "in_avg": 39.0, 7 | "in_max": 39, 8 | "in_min": 39, 9 | "local_addr": "*", 10 | "local_name": "UNKNOWN", 11 | "node": 1, 12 | "num_operations": 1, 13 | "operation_rate": 0.2000000029802322, 14 | "out": 0.0, 15 | "out_avg": 0.0, 16 | "out_max": 0, 17 | "out_min": 0, 18 | "protocol": "nfs3", 19 | "remote_addr": "127.0.0.1", 20 | "remote_name": "UNKNOWN", 21 | "time": 1651131929, 22 | "time_avg": 7.0, 23 | "time_max": 7, 24 | "time_min": 7, 25 | "user": {} 26 | }, 27 | { 28 | "class": "other", 29 | "in": 0.0, 30 | "in_avg": 0.0, 31 | "in_max": 0, 32 | "in_min": 0, 33 | "local_addr": "*", 34 | "local_name": "UNKNOWN", 35 | "node": 2, 36 | "num_operations": 1, 37 | "operation_rate": 0.2000000029802322, 38 | "out": 7.800000190734863, 39 | "out_avg": 39.0, 40 | "out_max": 39, 41 | "out_min": 39, 42 | "protocol": "siq", 43 | "remote_addr": "*", 44 | "remote_name": "UNKNOWN", 45 | "time": 1651131929, 46 | "time_avg": 68.0, 47 | "time_max": 68, 48 | "time_min": 68, 49 | "user": {} 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /service/mock/volume/get_non_existent_volume.txt: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "code": "AEC_NOT_FOUND", 5 | "message": "Unable to open object 'data/csi-isilon/volume1' in store 'ifs' -- not found." 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /service/mock/volume/get_volume2_without_metadata.txt: -------------------------------------------------------------------------------- 1 | { 2 | "children": [ 3 | { 4 | "name": "hello_world.txt" 5 | }, 6 | { 7 | "name": "sub" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /service/mock/volume/get_volume_size.txt: -------------------------------------------------------------------------------- 1 | {"children":[{ 2 | "name" : "d1", 3 | "size" : 40 4 | } 5 | ,{ 6 | "name" : "d2", 7 | "size" : 20 8 | } 9 | ,{ 10 | "name" : "f3", 11 | "size" : 457 12 | } 13 | ,{ 14 | "name" : "f2", 15 | "size" : 457 16 | } 17 | ,{ 18 | "name" : "f1", 19 | "size" : 457 20 | } 21 | ]} 22 | -------------------------------------------------------------------------------- /service/test/tmp/datafile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/csi-powerscale/4b9dfd3603b37403b4040c8bffe6c96554a8dd42/service/test/tmp/datafile -------------------------------------------------------------------------------- /service/test/tmp/datafile2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/csi-powerscale/4b9dfd3603b37403b4040c8bffe6c96554a8dd42/service/test/tmp/datafile2 -------------------------------------------------------------------------------- /test/helm/.gitignore: -------------------------------------------------------------------------------- 1 | __*__.yaml 2 | 3 | -------------------------------------------------------------------------------- /test/helm/10vols/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: 10vols 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Tests isilon CSI deployments. 19 | keywords: 20 | - csi-isilon 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/helm/10vols/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol0 18 | namespace: {{ .Values.namespace }} 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | --- 28 | kind: PersistentVolumeClaim 29 | apiVersion: v1 30 | metadata: 31 | name: pvol1 32 | namespace: {{ .Values.namespace }} 33 | spec: 34 | accessModes: 35 | - ReadWriteOnce 36 | volumeMode: Filesystem 37 | resources: 38 | requests: 39 | storage: 8Gi 40 | storageClassName: isilon 41 | --- 42 | kind: PersistentVolumeClaim 43 | apiVersion: v1 44 | metadata: 45 | name: pvol2 46 | namespace: {{ .Values.namespace }} 47 | spec: 48 | accessModes: 49 | - ReadWriteOnce 50 | volumeMode: Filesystem 51 | resources: 52 | requests: 53 | storage: 8Gi 54 | storageClassName: isilon 55 | --- 56 | kind: PersistentVolumeClaim 57 | apiVersion: v1 58 | metadata: 59 | name: pvol3 60 | namespace: {{ .Values.namespace }} 61 | spec: 62 | accessModes: 63 | - ReadWriteOnce 64 | volumeMode: Filesystem 65 | resources: 66 | requests: 67 | storage: 8Gi 68 | storageClassName: isilon 69 | --- 70 | kind: PersistentVolumeClaim 71 | apiVersion: v1 72 | metadata: 73 | name: pvol4 74 | namespace: {{ .Values.namespace }} 75 | spec: 76 | accessModes: 77 | - ReadWriteOnce 78 | volumeMode: Filesystem 79 | resources: 80 | requests: 81 | storage: 8Gi 82 | storageClassName: isilon 83 | --- 84 | kind: PersistentVolumeClaim 85 | apiVersion: v1 86 | metadata: 87 | name: pvol5 88 | namespace: {{ .Values.namespace }} 89 | spec: 90 | accessModes: 91 | - ReadWriteOnce 92 | volumeMode: Filesystem 93 | resources: 94 | requests: 95 | storage: 8Gi 96 | storageClassName: isilon 97 | --- 98 | kind: PersistentVolumeClaim 99 | apiVersion: v1 100 | metadata: 101 | name: pvol6 102 | namespace: {{ .Values.namespace }} 103 | spec: 104 | accessModes: 105 | - ReadWriteOnce 106 | volumeMode: Filesystem 107 | resources: 108 | requests: 109 | storage: 8Gi 110 | storageClassName: isilon 111 | --- 112 | kind: PersistentVolumeClaim 113 | apiVersion: v1 114 | metadata: 115 | name: pvol7 116 | namespace: {{ .Values.namespace }} 117 | spec: 118 | accessModes: 119 | - ReadWriteOnce 120 | volumeMode: Filesystem 121 | resources: 122 | requests: 123 | storage: 8Gi 124 | storageClassName: isilon 125 | --- 126 | kind: PersistentVolumeClaim 127 | apiVersion: v1 128 | metadata: 129 | name: pvol8 130 | namespace: {{ .Values.namespace }} 131 | spec: 132 | accessModes: 133 | - ReadWriteOnce 134 | volumeMode: Filesystem 135 | resources: 136 | requests: 137 | storage: 8Gi 138 | storageClassName: isilon 139 | --- 140 | kind: PersistentVolumeClaim 141 | apiVersion: v1 142 | metadata: 143 | name: pvol9 144 | namespace: {{ .Values.namespace }} 145 | spec: 146 | accessModes: 147 | - ReadWriteOnce 148 | volumeMode: Filesystem 149 | resources: 150 | requests: 151 | storage: 8Gi 152 | storageClassName: isilon 153 | --- 154 | -------------------------------------------------------------------------------- /test/helm/10vols/templates/test.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: isilontest 18 | namespace: {{ .Values.namespace }} 19 | --- 20 | kind: StatefulSet 21 | apiVersion: apps/v1 22 | metadata: 23 | name: isilontest 24 | namespace: {{ .Values.namespace }} 25 | spec: 26 | serviceName: "isilontest" 27 | selector: 28 | matchLabels: 29 | app: isilontest 30 | template: 31 | metadata: 32 | labels: 33 | app: isilontest 34 | spec: 35 | serviceAccount: isilontest 36 | hostNetwork: true 37 | containers: 38 | - name: test 39 | image: quay.io/centos/centos:latest 40 | command: [ "/bin/sleep", "3600" ] 41 | volumeMounts: 42 | - mountPath: "/data0" 43 | name: pvol0 44 | - mountPath: "/data1" 45 | name: pvol1 46 | - mountPath: "/data2" 47 | name: pvol2 48 | - mountPath: "/data3" 49 | name: pvol3 50 | - mountPath: "/data4" 51 | name: pvol4 52 | - mountPath: "/data5" 53 | name: pvol5 54 | - mountPath: "/data6" 55 | name: pvol6 56 | - mountPath: "/data7" 57 | name: pvol7 58 | - mountPath: "/data8" 59 | name: pvol8 60 | - mountPath: "/data9" 61 | name: pvol9 62 | volumes: 63 | - name: pvol0 64 | persistentVolumeClaim: 65 | claimName: pvol0 66 | - name: pvol1 67 | persistentVolumeClaim: 68 | claimName: pvol1 69 | - name: pvol2 70 | persistentVolumeClaim: 71 | claimName: pvol2 72 | - name: pvol3 73 | persistentVolumeClaim: 74 | claimName: pvol3 75 | - name: pvol4 76 | persistentVolumeClaim: 77 | claimName: pvol4 78 | - name: pvol5 79 | persistentVolumeClaim: 80 | claimName: pvol5 81 | - name: pvol6 82 | persistentVolumeClaim: 83 | claimName: pvol6 84 | - name: pvol7 85 | persistentVolumeClaim: 86 | claimName: pvol7 87 | - name: pvol8 88 | persistentVolumeClaim: 89 | claimName: pvol8 90 | - name: pvol9 91 | persistentVolumeClaim: 92 | claimName: pvol9 93 | -------------------------------------------------------------------------------- /test/helm/1vol/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: 1vol 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Test CSI Isilon deployment. 19 | keywords: 20 | - csi-isilon 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/createSnapshot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: snapshot.storage.k8s.io/v1 15 | kind: VolumeSnapshot 16 | metadata: 17 | name: pvol0-snap1 18 | namespace: test 19 | spec: 20 | volumeSnapshotClassName: isilon-snapclass 21 | source: 22 | persistentVolumeClaimName: pvol0 23 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/createVolumeFromSnapshot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvc-2 18 | namespace: test 19 | spec: 20 | accessModes: 21 | - ReadOnlyMany 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | dataSource: 28 | kind: VolumeSnapshot 29 | name: snap-1 30 | apiGroup: snapshot.storage.k8s.io 31 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/createVolumeFromVolume.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvc-2 18 | namespace: test 19 | spec: 20 | accessModes: 21 | - ReadOnlyMany 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | dataSource: 28 | kind: PersistentVolumeClaim 29 | name: pvc-1 30 | apiGroup: "" 31 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/pvc0.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol0 18 | namespace: test 19 | spec: 20 | accessModes: 21 | - ReadOnlyMany 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/test_pod.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: Pod 16 | metadata: 17 | name: isilontestpod1 18 | namespace: test 19 | spec: 20 | containers: 21 | - name: test 22 | image: quay.io/centos/centos:latest 23 | command: [ "/bin/sleep", "3600" ] 24 | volumeMounts: 25 | - mountPath: "/data0" 26 | name: pvol0 27 | volumes: 28 | - name: pvol0 29 | persistentVolumeClaim: 30 | claimName: pvol0 31 | -------------------------------------------------------------------------------- /test/helm/1vol/templates/test_statefulset.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: isilontest 18 | namespace: test 19 | --- 20 | kind: StatefulSet 21 | apiVersion: apps/v1 22 | metadata: 23 | name: isilontest 24 | namespace: test 25 | spec: 26 | serviceName: "isilontest" 27 | selector: 28 | matchLabels: 29 | app: isilontest 30 | template: 31 | metadata: 32 | labels: 33 | app: isilontest 34 | spec: 35 | serviceAccount: isilontest 36 | hostNetwork: true 37 | containers: 38 | - name: test 39 | image: quay.io/centos/centos:latest 40 | command: [ "/bin/sleep", "3600" ] 41 | volumeMounts: 42 | - mountPath: "/data0" 43 | name: pvol0 44 | volumes: 45 | - name: pvol0 46 | persistentVolumeClaim: 47 | claimName: pvol0 48 | -------------------------------------------------------------------------------- /test/helm/2vols+restore/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: 2vols+restore 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Tests Isilon CSI deployments. 19 | keywords: 20 | - isilon-csi 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/helm/2vols+restore/templates/createFromSnap.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: PersistentVolumeClaim 16 | metadata: 17 | name: restorepvc 18 | namespace: test 19 | spec: 20 | storageClassName: isilon 21 | volumeMode: Filesystem 22 | dataSource: 23 | name: pvol0-snap1 24 | kind: VolumeSnapshot 25 | apiGroup: snapshot.storage.k8s.io 26 | accessModes: 27 | - ReadWriteOnce 28 | resources: 29 | requests: 30 | storage: 8Gi 31 | -------------------------------------------------------------------------------- /test/helm/2vols+restore/templates/pvc0.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol0 18 | namespace: test 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/helm/2vols+restore/templates/pvc1.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol1 18 | namespace: test 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 12Gi 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/helm/2vols+restore/templates/test.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: isilontest 18 | namespace: test 19 | --- 20 | kind: StatefulSet 21 | apiVersion: apps/v1 22 | metadata: 23 | name: isilontest 24 | namespace: test 25 | spec: 26 | serviceName: "isilontest" 27 | selector: 28 | matchLabels: 29 | app: isilontest 30 | template: 31 | metadata: 32 | labels: 33 | app: isilontest 34 | spec: 35 | serviceAccount: isilontest 36 | hostNetwork: true 37 | containers: 38 | - name: test 39 | image: quay.io/centos/centos:latest 40 | command: [ "/bin/sleep", "3600" ] 41 | volumeMounts: 42 | - mountPath: "/data0" 43 | name: pvol0 44 | - mountPath: "/data1" 45 | name: pvol1 46 | - mountPath: "/data2" 47 | name: pvol2 48 | volumes: 49 | - name: pvol0 50 | persistentVolumeClaim: 51 | claimName: pvol0 52 | - name: pvol1 53 | persistentVolumeClaim: 54 | claimName: pvol1 55 | - name: pvol2 56 | persistentVolumeClaim: 57 | claimName: restorepvc 58 | -------------------------------------------------------------------------------- /test/helm/2vols/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: 2vols 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Tests isilon CSI deployments. 19 | keywords: 20 | - csi-isilon 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/helm/2vols/templates/pvc0.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol0 18 | namespace: {{ .Values.namespace }} 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/helm/2vols/templates/pvc1.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol1 18 | namespace: {{ .Values.namespace }} 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 12Gi 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/helm/2vols/templates/test.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: isilontest 18 | namespace: {{ .Values.namespace }} 19 | --- 20 | kind: StatefulSet 21 | apiVersion: apps/v1 22 | metadata: 23 | name: isilontest 24 | namespace: {{ .Values.namespace }} 25 | spec: 26 | serviceName: "isilontest" 27 | selector: 28 | matchLabels: 29 | app: isilontest 30 | template: 31 | metadata: 32 | labels: 33 | app: isilontest 34 | spec: 35 | serviceAccount: isilontest 36 | hostNetwork: true 37 | containers: 38 | - name: test 39 | image: quay.io/centos/centos:latest 40 | command: [ "/bin/sleep", "3600" ] 41 | volumeMounts: 42 | - mountPath: "/data0" 43 | name: pvol0 44 | - mountPath: "/data1" 45 | name: pvol1 46 | volumes: 47 | - name: pvol0 48 | persistentVolumeClaim: 49 | claimName: pvol0 50 | - name: pvol1 51 | persistentVolumeClaim: 52 | claimName: pvol1 53 | -------------------------------------------------------------------------------- /test/helm/7vols/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: 7vols 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Tests CSI deployments. 19 | keywords: 20 | - csi-isilon 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/helm/7vols/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | kind: PersistentVolumeClaim 15 | apiVersion: v1 16 | metadata: 17 | name: pvol0 18 | namespace: {{ .Values.namespace }} 19 | spec: 20 | accessModes: 21 | - ReadWriteOnce 22 | volumeMode: Filesystem 23 | resources: 24 | requests: 25 | storage: 8Gi 26 | storageClassName: isilon 27 | --- 28 | kind: PersistentVolumeClaim 29 | apiVersion: v1 30 | metadata: 31 | name: pvol1 32 | namespace: {{ .Values.namespace }} 33 | spec: 34 | accessModes: 35 | - ReadWriteOnce 36 | volumeMode: Filesystem 37 | resources: 38 | requests: 39 | storage: 8Gi 40 | storageClassName: isilon 41 | --- 42 | kind: PersistentVolumeClaim 43 | apiVersion: v1 44 | metadata: 45 | name: pvol2 46 | namespace: {{ .Values.namespace }} 47 | spec: 48 | accessModes: 49 | - ReadWriteOnce 50 | volumeMode: Filesystem 51 | resources: 52 | requests: 53 | storage: 8Gi 54 | storageClassName: isilon 55 | --- 56 | kind: PersistentVolumeClaim 57 | apiVersion: v1 58 | metadata: 59 | name: pvol3 60 | namespace: {{ .Values.namespace }} 61 | spec: 62 | accessModes: 63 | - ReadWriteOnce 64 | volumeMode: Filesystem 65 | resources: 66 | requests: 67 | storage: 8Gi 68 | storageClassName: isilon 69 | --- 70 | kind: PersistentVolumeClaim 71 | apiVersion: v1 72 | metadata: 73 | name: pvol4 74 | namespace: {{ .Values.namespace }} 75 | spec: 76 | accessModes: 77 | - ReadWriteOnce 78 | volumeMode: Filesystem 79 | resources: 80 | requests: 81 | storage: 8Gi 82 | storageClassName: isilon 83 | --- 84 | kind: PersistentVolumeClaim 85 | apiVersion: v1 86 | metadata: 87 | name: pvol5 88 | namespace: {{ .Values.namespace }} 89 | spec: 90 | accessModes: 91 | - ReadWriteOnce 92 | volumeMode: Filesystem 93 | resources: 94 | requests: 95 | storage: 8Gi 96 | storageClassName: isilon 97 | --- 98 | kind: PersistentVolumeClaim 99 | apiVersion: v1 100 | metadata: 101 | name: pvol6 102 | namespace: {{ .Values.namespace }} 103 | spec: 104 | accessModes: 105 | - ReadWriteOnce 106 | volumeMode: Filesystem 107 | resources: 108 | requests: 109 | storage: 8Gi 110 | storageClassName: isilon 111 | -------------------------------------------------------------------------------- /test/helm/7vols/templates/test.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: isilontest 18 | namespace: {{ .Values.namespace }} 19 | --- 20 | kind: StatefulSet 21 | apiVersion: apps/v1 22 | metadata: 23 | name: isilontest 24 | namespace: {{ .Values.namespace }} 25 | spec: 26 | serviceName: "isilontest" 27 | selector: 28 | matchLabels: 29 | app: isilontest 30 | template: 31 | metadata: 32 | labels: 33 | app: isilontest 34 | spec: 35 | serviceAccount: isilontest 36 | hostNetwork: true 37 | containers: 38 | - name: test 39 | image: quay.io/centos/centos:latest 40 | command: [ "/bin/sleep", "3600" ] 41 | volumeMounts: 42 | - mountPath: "/data0" 43 | name: pvol0 44 | - mountPath: "/data1" 45 | name: pvol1 46 | - mountPath: "/data2" 47 | name: pvol2 48 | - mountPath: "/data3" 49 | name: pvol3 50 | - mountPath: "/data4" 51 | name: pvol4 52 | - mountPath: "/data5" 53 | name: pvol5 54 | - mountPath: "/data6" 55 | name: pvol6 56 | volumes: 57 | - name: pvol0 58 | persistentVolumeClaim: 59 | claimName: pvol0 60 | - name: pvol1 61 | persistentVolumeClaim: 62 | claimName: pvol1 63 | - name: pvol2 64 | persistentVolumeClaim: 65 | claimName: pvol2 66 | - name: pvol3 67 | persistentVolumeClaim: 68 | claimName: pvol3 69 | - name: pvol4 70 | persistentVolumeClaim: 71 | claimName: pvol4 72 | - name: pvol5 73 | persistentVolumeClaim: 74 | claimName: pvol5 75 | - name: pvol6 76 | persistentVolumeClaim: 77 | claimName: pvol6 78 | -------------------------------------------------------------------------------- /test/helm/README.md: -------------------------------------------------------------------------------- 1 | # Various test Helm charts and test scripts 2 | 3 | ## Helm charts 4 | 5 | | Name | Usage | 6 | |---------|-------| 7 | |1vol | Creates 1 filesystem mount | 8 | |2vols | Creates 2 filesystem mounts | 9 | |7vols | Creates 7 filesystem mounts | 10 | |10vols | Creates 10 filesystem mounts | 11 | |2vols+restore | Upgraded version of 2vols that also mounts a volume created from snap | 12 | 13 | ## Scripts 14 | 15 | | Name | Usage | 16 | |----------------|-------| 17 | | deletepvcs.sh | Script to delete all PVCS in a namespace | 18 | | get.volume.ids | Script to list the volume IDs for all PVS | 19 | | logit.sh | Script to print number of pods and pvcs in a namespace | 20 | | starttest.sh | Used to instantiate one of the Helm charts above. Requires argument of Helm chart | 21 | | stoptest.sh | Stops currently running Helm chart and deletes all PVCS | 22 | | snaptest.sh | Script to create volume and snapshot from volume | 23 | | snaprestoretest.sh | Script to instantiate 2vols; then upgrade to 2vols+restore (with volume from snapshot) | 24 | 25 | ## Usage 26 | 27 | The starttest.sh script is used to deploy Helm charts that test the deployment of a simple pod 28 | with various storage configurations. The stoptest.sh script will delete the Helm chart and cleanup after the test. 29 | Procedure 30 | 31 | 1. Navigate to the test/helm directory, which contains the starttest.sh and various Helm charts. 32 | 33 | 2. Run the starttest.sh script with an argument of the specific Helm chart to deploy and test. For example: 34 | 35 | > ./starttest.sh -t 2vols 36 | 37 | 3. After the test has completed, run the stoptest.sh script to delete the Helm chart and cleanup the volumes. 38 | 39 | > ./stoptest.sh -t 2vols 40 | -------------------------------------------------------------------------------- /test/helm/deletepvcs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright © 2019-2020 Dell Inc. or its subsidiaries. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License 14 | 15 | force=no 16 | NAMESPACE="test" 17 | 18 | # Usage information 19 | function usage { 20 | echo 21 | echo "`basename ${0}`" 22 | echo " -n namespace - Namespace in which the release is running. Default is: ${NAMESPACE}" 23 | echo " -f - force delete" 24 | exit 1 25 | } 26 | 27 | # Parse the options passed on the command line 28 | while getopts "fn:" opt; do 29 | case $opt in 30 | n) 31 | NAMESPACE="${OPTARG}" 32 | ;; 33 | f) 34 | force=yes 35 | ;; 36 | \?) 37 | echo "Invalid option: -$OPTARG" >&2 38 | usage 39 | ;; 40 | :) 41 | echo "Option -$OPTARG requires an argument." >&2 42 | usage 43 | ;; 44 | esac 45 | done 46 | 47 | pvcs=$(kubectl get pvc -n $NAMESPACE | awk '/pvol/ { print $1; }') 48 | echo deleting... $pvcs 49 | for pvc in $pvcs 50 | do 51 | if [ $force == "yes" ]; 52 | then 53 | echo kubectl delete --force --grace-period=0 pvc $pvc -n $NAMESPACE 54 | kubectl delete --force --grace-period=0 pvc $pvc -n $NAMESPACE 55 | else 56 | echo kubectl delete pvc $pvc -n $NAMESPACE 57 | kubectl delete pvc $pvc -n $NAMESPACE 58 | fi 59 | done 60 | 61 | -------------------------------------------------------------------------------- /test/helm/get.volume.ids: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ids=$(kubectl describe persistentvolume -n test | grep VolumeHandle | awk ' { print $2; }') 3 | echo ids $ids 4 | ids=$(echo $ids | tr ' ' ',' ) 5 | echo ids $ids 6 | -------------------------------------------------------------------------------- /test/helm/logit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2021 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | while true 15 | do 16 | date 17 | date >>log.output 18 | running=$(kubectl get pods -n test --no-headers=true | grep "Running" | wc -l) 19 | creating=$(kubectl get pods -n test --no-headers=true | grep "ContainerCreating" | wc -l) 20 | pvcs=$(kubectl get pvc -n test --no-headers=true | wc -l) 21 | echo pods running $running, pods creating $creating, pvcs count $pvcs 22 | echo pods running $running, pods creating $creating, pvcs count $pvcs >>log.output 23 | sleep 30 24 | done 25 | 26 | -------------------------------------------------------------------------------- /test/helm/snap1.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: snapshot.storage.k8s.io/v1 15 | kind: VolumeSnapshot 16 | metadata: 17 | name: pvol0-snap1 18 | namespace: test 19 | spec: 20 | volumeSnapshotClassName: isilon-snapclass 21 | source: 22 | persistentVolumeClaimName: pvol0 23 | -------------------------------------------------------------------------------- /test/helm/snap2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: snapshot.storage.k8s.io/v1 15 | kind: VolumeSnapshot 16 | metadata: 17 | name: pvol0-snap2 18 | namespace: test 19 | spec: 20 | volumeSnapshotClassName: isilon-snapclass 21 | source: 22 | persistentVolumeClaimName: pvol0 23 | -------------------------------------------------------------------------------- /test/helm/snaprestoretest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2020 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | echo "installing a 2 volume container" 15 | sh starttest.sh -t 2vols 16 | echo "done installing a 2 volume container" 17 | 18 | echo "marking volume" 19 | kubectl exec -n test isilontest-0 -- touch /data0/orig 20 | kubectl exec -n test isilontest-0 -- ls -l /data0 21 | kubectl exec -n test isilontest-0 -- sync 22 | kubectl exec -n test isilontest-0 -- sync 23 | 24 | echo "creating snap1 of pvol0" 25 | kubectl create -f snap1.yaml 26 | sleep 20 27 | kubectl get volumesnapshot -n test 28 | 29 | echo "updating container to add a volume sourced from snapshot" 30 | helm upgrade 2vols 2vols+restore 31 | echo "waiting for container to upgrade/stabalize" 32 | sleep 20 33 | up=0 34 | while [ $up -lt 1 ]; do 35 | sleep 5 36 | kubectl get pods -n test 37 | up=`kubectl get pods -n test | grep '1/1 *Running' | wc -l` 38 | done 39 | kubectl describe pods -n test 40 | kubectl exec -n test isilontest-0 -it df | grep data 41 | kubectl exec -n test isilontest-0 -it mount | grep data 42 | echo "updating container finished" 43 | 44 | echo "marking volume" 45 | kubectl exec -n test isilontest-0 -- touch /data2/new 46 | echo "listing /data0" 47 | kubectl exec -n test isilontest-0 -- ls -l /data0 48 | echo "listing /data2" 49 | kubectl exec -n test isilontest-0 -- ls -l /data2 50 | sleep 20 51 | 52 | echo "deleting container" 53 | sh stoptest.sh -t 2vols 54 | sleep 5 55 | 56 | echo "deleting snap" 57 | kubectl delete volumesnapshot pvol0-snap1 -n test 58 | -------------------------------------------------------------------------------- /test/helm/snaptest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2020 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | echo "creating snap1 of pvol0" 15 | kubectl create -f snap1.yaml 16 | sleep 10 17 | kubectl get volumesnapshot -n test 18 | kubectl describe volumesnapshot -n test 19 | sleep 10 20 | 21 | echo "creating snap2 of pvol0" 22 | kubectl create -f snap2.yaml 23 | sleep 10 24 | kubectl describe volumesnapshot -n test 25 | sleep 10 26 | 27 | echo "deleting snapshots..." 28 | kubectl delete volumesnapshot pvol0-snap1 -n test 29 | sleep 10 30 | kubectl delete volumesnapshot pvol0-snap2 -n test 31 | sleep 10 32 | kubectl get volumesnapshot -n test 33 | -------------------------------------------------------------------------------- /test/helm/starttest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2020 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | TEST="" 15 | NAMESPACE="test" 16 | 17 | # Usage information 18 | function usage { 19 | echo 20 | echo "`basename ${0}`" 21 | echo " -t test - Test to run. Should be the name of a directory holding a Helm Chart" 22 | echo " -n namespace - Namespace in which to place the test. Default is: ${NAMESPACE}" 23 | exit 1 24 | } 25 | 26 | # Parse the options passed on the command line 27 | while getopts "t:n:" opt; do 28 | case $opt in 29 | t) 30 | TEST="${OPTARG}" 31 | ;; 32 | n) 33 | NAMESPACE="${OPTARG}" 34 | ;; 35 | \?) 36 | echo "Invalid option: -$OPTARG" >&2 37 | usage 38 | ;; 39 | :) 40 | echo "Option -$OPTARG requires an argument." >&2 41 | usage 42 | ;; 43 | esac 44 | done 45 | 46 | waitOnRunning() { 47 | if [ "$1" = "" ]; 48 | then echo "arg: target" ; 49 | exit 2; 50 | fi 51 | WAITINGFOR=$1 52 | 53 | RUNNING=$(kubectl get pods -n "${NAMESPACE}" | grep "Running" | wc -l) 54 | while [ $RUNNING -ne $WAITINGFOR ]; 55 | do 56 | RUNNING=$(kubectl get pods -n "${NAMESPACE}" | grep "Running" | wc -l) 57 | CREATING=$(kubectl get pods -n "${NAMESPACE}" | grep "ContainerCreating" | wc -l) 58 | TERMINATING=$(kubectl get pods -n "${NAMESPACE}" | grep "Terminating" | wc -l) 59 | PVCS=$(kubectl get pvc -n "${NAMESPACE}" | grep -v "STATUS" | wc -l) 60 | date 61 | date >>log.output 62 | echo running $RUNNING creating $CREATING terminating $TERMINATING pvcs $PVCS 63 | echo running $RUNNING creating $CREATING terminating $TERMINATING pvcs $PVCS >>log.output 64 | sleep 30 65 | done 66 | } 67 | 68 | 69 | # Ensure a test was named and that it exists 70 | if [ "${TEST}" == "" ]; then 71 | echo "The name of a test must be specified" 72 | usage 73 | fi 74 | if [ ! -d "${TEST}" ]; then 75 | echo "Unable to find test named: ${TEST}" 76 | usage 77 | fi 78 | 79 | # Validate that the namespace exists 80 | NUM=`kubectl get namespaces | grep "^${NAMESPACE} " | wc -l` 81 | if [ $NUM -ne 1 ]; then 82 | echo "Unable to find a namespace called: ${NAMESPACE}" 83 | exit 1 84 | fi 85 | 86 | # the helm release name will be the basename of the test 87 | RELEASE=`basename "${TEST}"` 88 | 89 | # create a temporary values file to hold the user supplied information 90 | VALUES="__${NAMESPACE}-${RELEASE}__.yaml" 91 | if [ -f "${VALUES}" ]; then 92 | echo "There appears to already be a release/test named ${RELEASE} in namespace ${NAMESPACE}" 93 | echo "Please stop it with the stoptest.sh script before starting another" 94 | exit 1 95 | fi 96 | 97 | echo "namespace: ${NAMESPACE}" >> "${VALUES}" 98 | echo "release: ${RELEASE}" >> "${VALUES}" 99 | 100 | # Start the tests 101 | helm version | grep "v3." --quiet 102 | if [ $? -eq 0 ]; then 103 | helm install "${RELEASE}" -f "${VALUES}" "${TEST}" 104 | else 105 | helm install --name "${RELEASE}" -f "${VALUES}" "${TEST}" 106 | fi 107 | 108 | echo "waiting 60 seconds on pod to initialize" 109 | sleep 60 110 | kubectl describe pods -n "${NAMESPACE}" 111 | waitOnRunning 1 112 | kubectl describe pods -n "${NAMESPACE}" 113 | kubectl exec -n "${NAMESPACE}" isilontest-0 -it df | grep data 114 | kubectl exec -n "${NAMESPACE}" isilontest-0 -it mount | grep data 115 | -------------------------------------------------------------------------------- /test/helm/stoptest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2020 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | TEST="" 15 | NAMESPACE="test" 16 | 17 | # Usage information 18 | function usage { 19 | echo 20 | echo "`basename ${0}`" 21 | echo " -t test - Test to stop" 22 | echo " -n namespace - Namespace in which the release is running. Default is: ${NAMESPACE}" 23 | exit 1 24 | } 25 | 26 | # Parse the options passed on the command line 27 | while getopts "t:n:" opt; do 28 | case $opt in 29 | t) 30 | TEST="${OPTARG}" 31 | ;; 32 | n) 33 | NAMESPACE="${OPTARG}" 34 | ;; 35 | \?) 36 | echo "Invalid option: -$OPTARG" >&2 37 | usage 38 | ;; 39 | :) 40 | echo "Option -$OPTARG requires an argument." >&2 41 | usage 42 | ;; 43 | esac 44 | done 45 | 46 | # Ensure a test was named and that it exists 47 | if [ "${TEST}" == "" ]; then 48 | echo "The name of a test must be specified" 49 | usage 50 | fi 51 | if [ ! -d "${TEST}" ]; then 52 | echo "Unable to find test named: ${TEST}" 53 | usage 54 | fi 55 | 56 | # the helm release name will be the basename of the test 57 | RELEASE=`basename "${TEST}"` 58 | 59 | VALUES="__${NAMESPACE}-${RELEASE}__.yaml" 60 | 61 | helm version | grep "v3." --quiet 62 | if [ $? -eq 0 ]; then 63 | helm delete "${RELEASE}" 64 | else 65 | helm delete --purge "${RELEASE}" 66 | fi 67 | 68 | sleep 10 69 | kubectl get pods -n "${NAMESPACE}" 70 | echo "waiting for persistent volumes to be cleaned up" 71 | sleep 90 72 | sh deletepvcs.sh -n "${NAMESPACE}" 73 | kubectl get persistentvolumes -o wide 74 | 75 | if [ -f "${VALUES}" ]; then 76 | rm "${VALUES}" 77 | fi 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /test/ingestion/README.md: -------------------------------------------------------------------------------- 1 | # Volume Ingestion 2 | This script is for static provisioning in csi-powerscale. You can manage volumes which exist on PowerScale but were created outside of CSI driver. 3 | ## Prerequisites 4 | The NFS export corresponding to the directory needs to exist. It's ID would be used in the volumehandle as described below. It need not have the kubernetes nodes added as clients. 5 | 6 | If Quotas are enabled in the driver, it is recommended that you add the Quota ID to the description of the NFS export in the following format: 7 | CSI_QUOTA_ID:sC-kAAEAAAAAAAAAAAAAQEpVAAAAAAAA 8 | 9 | The details of various Quotas can be obtained via the following REST API of OneFS: 10 | GET 11 | /platform/1/quota/quotas 12 | 13 | Starting from csi-powerscale 1.5, volume handle should include cluster name also (due to multi array support) 14 | 15 | Volume Handle is expected to be present in this pattern VolName + VolumeIDSeparator + exportID + VolumeIDSeparator + accessZone + clusterName for ex. "demovol1=\_=\_=303=\_=\_=System_=\_=cluster" 16 | 17 | ## Running the script 18 | Command Line inputs are taken in this order: volumename, volumehandle, storageclassname, accessmode, storage size, pvname, pvcname 19 | ## Examples 20 | To provision a Volume named sample14 in access zone csi-zone having export-id as 6 and cluster name 'cluster1', volumehandle will be sample14=\_=\_=6=\_=\_=csi-zone=\_=\_=cluster1. Here we are using a custom storage class named as customstorageclass1, access mode as ReadWriteMany, storage size as 500M, pv name as pv1, pvc name as pvc1, we will be running : 21 | 22 | ./ingestion_test.sh sample14 sample14=\_=\_=6=\_=\_=csi-zone=\_=\_=cluster1 customstorageclass1 ReadWriteMany 500M pv1 pvc1 23 | -------------------------------------------------------------------------------- /test/ingestion/ingestion_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright © 2020-2021 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # volumename volumehandle storageclass accessmode storagesize pvname pvcname clustername 15 | # 1 2 3 4 5 6 7 8 16 | 17 | if [[ $2 =~ ^[a-zA-Z0-9_-]+=_=_=[0-9]+=_=_=[a-zA-Z0-9_-]+=_=_=[a-zA-Z0-9_-]+$ ]] 18 | then 19 | echo "Volume handle pattern matched" 20 | 21 | #getting ip from storageclass: 22 | ip=$(kubectl get storageclass $3 -o yaml| grep AzServiceIP: | tail -1 | cut -d ':' -f 2,2| sed -e 's/^[[:space:]]*//' ) 23 | 24 | #getting path from storageclass 25 | pathnew=$(kubectl get storageclass $3 -o yaml| grep IsiPath: | tail -1 | cut -d ':' -f 2,2| sed -e 's/^[[:space:]]*//' ) 26 | path="$pathnew/$1" 27 | 28 | #getting accesszone from storage class 29 | acz=$(kubectl get storageclass $3 -o yaml| grep AccessZone: |cut -d ':' -f 2,2| sed -e 's/^[[:space:]]*//' ) 30 | 31 | cat < static_pv_$6.yaml 32 | apiVersion: v1 33 | kind: PersistentVolume 34 | metadata: 35 | name: $6 36 | namespace: default 37 | spec: 38 | capacity: 39 | storage: "$5" 40 | accessModes: 41 | - "$4" 42 | persistentVolumeReclaimPolicy: Retain 43 | storageClassName: $3 44 | csi: 45 | driver: csi-isilon.dellemc.com 46 | volumeAttributes: 47 | Path: "$path" 48 | Name: "$1" 49 | AzServiceIP: '$ip' 50 | volumeHandle: $2 51 | claimRef: 52 | name: $7 53 | namespace: default 54 | EOF 55 | 56 | cat < static_pvc_$7.yaml 57 | apiVersion: v1 58 | kind: PersistentVolumeClaim 59 | metadata: 60 | name: $7 61 | namespace: default 62 | spec: 63 | accessModes: 64 | - "$4" 65 | resources: 66 | requests: 67 | storage: "$5" 68 | volumeName: "$6" 69 | EOF 70 | 71 | cat < static_pod.yaml 72 | apiVersion: v1 73 | kind: Pod 74 | metadata: 75 | name: testpod-script 76 | namespace: default 77 | spec: 78 | containers: 79 | - name: task-pv-containe 80 | image: nginx 81 | ports: 82 | - containerPort: 80 83 | name: "http-server" 84 | volumeMounts: 85 | - mountPath: "/usr/share/nginx/html" 86 | name: nov-eleventh-1-pv-storage 87 | volumes: 88 | - name: nov-eleventh-1-pv-storage 89 | persistentVolumeClaim: 90 | claimName: $7 91 | EOF 92 | 93 | kubectl create -f static_pv_$6.yaml 94 | echo "Persistent Volume $6 creation successful" 95 | kubectl create -f static_pvc_$7.yaml 96 | echo "Persistent Volume Claim $7 creation successful" 97 | kubectl create -f static_pod.yaml 98 | echo "Pod created successfully with ingested volume" 99 | 100 | #cleaning files created: 101 | rm -rf static_pv_$6.yaml static_pvc_$7.yaml static_pod.yaml 102 | 103 | else 104 | echo "Volume handle $2 pattern does not matched the regex: ^[a-zA-Z0-9_-]+=_=_=+[0-9]*=_=_=+[a-zA-Z0-9_-]+$" 105 | echo "Volume handle is expected in this format: demovol=_=_=251=_=_=System" 106 | 107 | fi 108 | echo "done" 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /test/ingestion/sample/isilonstaticpv.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: PersistentVolume 16 | metadata: 17 | name: isilonstaticpv 18 | namespace: default 19 | spec: 20 | capacity: 21 | storage: 5Gi 22 | accessModes: 23 | - ReadWriteMany 24 | persistentVolumeReclaimPolicy: Retain 25 | storageClassName: isilon 26 | csi: 27 | driver: csi-isilon.dellemc.com 28 | volumeAttributes: 29 | Path: "/ifs/data/csi/isilonvol" 30 | Name: "isilonvol" 31 | AzServiceIP: "XX.XX.XX.XX" 32 | volumeHandle: isilonvol=_=_=652=_=_=System=_=_=cluster 33 | claimRef: 34 | name: isilonstaticpvc 35 | namespace: default 36 | -------------------------------------------------------------------------------- /test/ingestion/sample/isilonstaticpvc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: v1 15 | kind: PersistentVolumeClaim 16 | metadata: 17 | name: isilonstaticpvc 18 | namespace: default 19 | spec: 20 | accessModes: 21 | - ReadWriteMany 22 | resources: 23 | requests: 24 | storage: 5Gi 25 | volumeName: isilonstaticpv 26 | storageClassName: isilon 27 | -------------------------------------------------------------------------------- /test/integration/README.md: -------------------------------------------------------------------------------- 1 | # Integration test for CSI PowerScale driver 2 | 3 | This test is run on a Kubernetes node, this will make real calls to the 4 | PowerScale. 5 | 6 | There are four scripts to set environment variables, env_Quota_Enabled.sh, env_Quota_notEnabled.sh, env_nodeIP1.sh, env_nodeIP2.sh. All files should be populated with values for PowerScale. env_Quota_Enabled.sh is used for Quota enabled, env_Quota_notEnabled.sh is for Quota not enabled. The file env_nodeIP1.sh and file env_nodeIP2.sh added to mock different node IPs for NodeStageVolume with different accessModes, the corresponding feature file is mock_different_nodeIPs.feature. The file main_integration.feature is used to test most scenarios. 7 | 8 | There is a config file to set secrets details, either this file can be updated or the path for the same can be updated in all the environment files, under the variable name 'X_CSI_ISI_CONFIG_PATH' 9 | 10 | To launch the integration test, just run `make integration-test` from csi-powerscale root directory. Whichever environment script, feature file and tag needed can be specified in this script. 11 | -------------------------------------------------------------------------------- /test/integration/config: -------------------------------------------------------------------------------- 1 | isilonClusters: 2 | - clusterName: "cluster1" 3 | username: "user" 4 | password: "password" 5 | isDefault: true 6 | endpoint: "1.2.3.4" 7 | skipCertificateValidation: true 8 | - clusterName: "cluster2" 9 | username: "user" 10 | password: "password" 11 | isDefault: false 12 | endpoint: "1.2.3.5" 13 | skipCertificateValidation: true 14 | -------------------------------------------------------------------------------- /test/integration/env_Custom_Topology_Enabled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2020-2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This should be like 111.222.333.444 15 | export X_CSI_CLUSTER_NAME="cluster1" 16 | export X_CSI_ISI_PATH="/ifs/data/csi/integration" 17 | export X_CSI_ISI_PORT="8080" 18 | export X_CSI_ISI_QUOTA_ENABLED="true" 19 | export X_CSI_CUSTOM_TOPOLOGY_ENABLED="true" 20 | export X_CSI_NODE_IP=`hostname -I | head -1 | awk ' { print $1; } '` 21 | NODENAME=`hostname` 22 | export X_CSI_NODE_NAME=$NODENAME 23 | export X_CSI_ISI_SKIP_CERTIFICATE_VALIDATION="true" 24 | export X_CSI_ISI_AUTOPROBE="true" 25 | export X_CSI_ISI_NO_PROBE_ON_START="false" 26 | export X_CSI_MODE="" 27 | export X_CSI_ISI_CONFIG_PATH=`pwd`/config 28 | 29 | # Variables for using tests 30 | export CSI_ENDPOINT=`pwd`/unix_sock 31 | -------------------------------------------------------------------------------- /test/integration/env_Quota_Enabled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This should be like 111.222.333.444 15 | export X_CSI_CLUSTER_NAME="cluster1" 16 | export X_CSI_ISI_PATH="/ifs/data/csi/integration" 17 | export X_CSI_ISI_PORT="8080" 18 | export X_CSI_ISI_QUOTA_ENABLED="true" 19 | export X_CSI_NODE_IP=`hostname -I | head -1 | awk ' { print $1; } '` 20 | NODEFQDN=`hostname -f` 21 | NODENAME=`hostname` 22 | SEPARATOR="=#=#=" 23 | NODEID=$NODENAME$SEPARATOR$NODEFQDN$SEPARATOR$X_CSI_NODE_IP 24 | export X_CSI_NODE_NAME=$NODEID 25 | export X_CSI_ISI_SKIP_CERTIFICATE_VALIDATION="true" 26 | export X_CSI_ISI_AUTOPROBE="true" 27 | export X_CSI_ISI_NO_PROBE_ON_START="false" 28 | export X_CSI_MODE="" 29 | export X_CSI_ISI_CONFIG_PATH=`pwd`/config 30 | export X_CSI_ISI_ACCESS_ZONE="integration-test-zone" 31 | export X_CSI_ISI_AZ_SERVICE_IP="1.2.3.4" 32 | 33 | # Variables for using tests 34 | export CSI_ENDPOINT=`pwd`/unix_sock 35 | -------------------------------------------------------------------------------- /test/integration/env_Quota_notEnabled.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This should be like 111.222.333.444 15 | export X_CSI_CLUSTER_NAME="cluster1" 16 | export X_CSI_ISI_PATH="/ifs/data/csi/integration" 17 | export X_CSI_ISI_PORT="8080" 18 | export X_CSI_ISI_QUOTA_ENABLED="false" 19 | export X_CSI_NODE_IP=`hostname -I | head -1 | awk ' { print $1; } '` 20 | NODEFQDN=`hostname -f` 21 | NODENAME=`hostname` 22 | SEPARATOR="=#=#=" 23 | NODEID=$NODENAME$SEPARATOR$NODEFQDN$SEPARATOR$X_CSI_NODE_IP 24 | export X_CSI_NODE_NAME=$NODEID 25 | export X_CSI_ISI_SKIP_CERTIFICATE_VALIDATION="true" 26 | export X_CSI_ISI_AUTOPROBE="true" 27 | export X_CSI_ISI_NO_PROBE_ON_START="false" 28 | export X_CSI_MODE="" 29 | export X_CSI_ISI_CONFIG_PATH=`pwd`/config 30 | export X_CSI_ISI_ACCESS_ZONE="integration-test-zone" 31 | export X_CSI_ISI_AZ_SERVICE_IP="1.2.3.4" 32 | 33 | # Variables for using tests 34 | export CSI_ENDPOINT=`pwd`/unix_sock 35 | -------------------------------------------------------------------------------- /test/integration/env_nodeIP1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This is used for mocking different node IPs in order to test accessModes 15 | 16 | # This should be like 111.222.333.444 17 | export X_CSI_CLUSTER_NAME="cluster1" 18 | export X_CSI_ISI_PATH="/ifs/data/csi/integration" 19 | export X_CSI_ISI_PORT="8080" 20 | export X_CSI_ISI_QUOTA_ENABLED="false" 21 | export X_CSI_NODE_IP="1.1.1.2" 22 | NODEFQDN=`hostname -f` 23 | NODENAME=`hostname` 24 | SEPARATOR="=#=#=" 25 | NODEID=$NODENAME$SEPARATOR$NODEFQDN$SEPARATOR$X_CSI_NODE_IP 26 | export X_CSI_NODE_NAME=$NODEID 27 | export X_CSI_ISI_SKIP_CERTIFICATE_VALIDATION="true" 28 | export X_CSI_ISI_AUTOPROBE="true" 29 | export X_CSI_ISI_NO_PROBE_ON_START="false" 30 | export X_CSI_MODE="" 31 | export X_CSI_ISI_CONFIG_PATH=`pwd`/config 32 | export X_CSI_ISI_ACCESS_ZONE="integration-test-zone" 33 | export X_CSI_ISI_AZ_SERVICE_IP="1.2.3.4" 34 | 35 | # Variables for using tests 36 | export CSI_ENDPOINT=`pwd`/unix_sock 37 | -------------------------------------------------------------------------------- /test/integration/env_nodeIP2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This is used for mocking different node IPs in order to test accessModes 15 | 16 | # This should be like 111.222.333.444 17 | export X_CSI_CLUSTER_NAME="cluster1" 18 | export X_CSI_ISI_PATH="/ifs/data/csi/integration" 19 | export X_CSI_ISI_PORT="8080" 20 | export X_CSI_ISI_QUOTA_ENABLED="false" 21 | export X_CSI_NODE_NAME="xyz=#=#=xyz.com=#=#=1.1.1.2" 22 | export X_CSI_NODE_IP="1.1.1.2" 23 | export X_CSI_ISI_SKIP_CERTIFICATE_VALIDATION="true" 24 | export X_CSI_ISI_AUTOPROBE="true" 25 | export X_CSI_ISI_NO_PROBE_ON_START="false" 26 | export X_CSI_MODE="" 27 | export X_CSI_ISI_CONFIG_PATH=`pwd`/config 28 | export X_CSI_ISI_ACCESS_ZONE="integration-test-zone" 29 | export X_CSI_ISI_AZ_SERVICE_IP="1.2.3.4" 30 | 31 | # Variables for using tests 32 | export CSI_ENDPOINT=`pwd`/unix_sock 33 | -------------------------------------------------------------------------------- /test/integration/features/integration.feature: -------------------------------------------------------------------------------- 1 | Feature: Isilon CSI interface 2 | As a consumer of the CSI interface 3 | I want to run a system test 4 | So that I know the service functions correctly 5 | 6 | @v1.0 7 | Scenario: Create and delete basic volume with/without Quota enabled 8 | Given a Isilon service 9 | And a basic volume request "integration0" "8" 10 | When I call CreateVolume 11 | Then there is a directory "integration0" 12 | Then there is an export "integration0" 13 | Then verify "integration0" size 14 | When I call DeleteVolume 15 | And there is not an export "integration0" 16 | And there is not a quota "integration0" 17 | Then there are no errors 18 | 19 | @v1.0 20 | Scenario: Idempotent create and delete basic volume with/without Quota enabled 21 | Given a Isilon service 22 | And a basic volume request "integration0" "8" 23 | When I call CreateVolume 24 | When I call CreateVolume 25 | Then there is a directory "integration0" 26 | Then there is an export "integration0" 27 | Then verify "integration0" size 28 | When I call DeleteVolume 29 | When I call DeleteVolume 30 | Then there is not a directory "integration0" 31 | Then there is not an export "integration0" 32 | 33 | @v1.0 34 | Scenario: Create volume, create snapshot, create volume from snapshot, delete original volume, delete new volume 35 | Given a Isilon service 36 | And a basic volume request "integration0" "8" 37 | When I call CreateVolume 38 | Then there is a directory "integration0" 39 | Then there is an export "integration0" 40 | Then verify "integration0" size 41 | When I call CreateSnapshot "snapshot0" "integration0" 42 | Then there is a snapshot "snapshot0" 43 | When I call CreateVolumeFromSnapshot "volFromSnap0" 44 | Then there is a directory "volFromSnap0" 45 | And there is an export "volFromSnap0" 46 | And verify "volFromSnap0" size 47 | When I call DeleteSnapshot 48 | Then there is not a snapshot "snapshot0" 49 | When I call DeleteVolume 50 | Then there is not a directory "volFromSnap0" 51 | And there is not an export "volFromSnap0" 52 | And there is not a quota "volFromSnap0" 53 | When I call DeleteAllVolumes 54 | Then there are no errors 55 | 56 | @v1.0 57 | Scenario Outline: Create, ControllerPublish, NodeStage, NodePublish, NodeUnpublish, NodeUnstage, ControllerUnpublish, delete basic volume 58 | Given a Isilon service 59 | And a capability with access 60 | And a volume request "integration0" "8" 61 | When I call CreateVolume 62 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 63 | Then check Isilon client exists "X_CSI_NODE_NAME" 64 | When I call NodeStageVolume 65 | Then there are no errors 66 | When I call NodePublishVolume "datadir0" 67 | Then verify published volume with access "datadir0" 68 | When I call NodeUnpublishVolume "datadir0" 69 | Then verify not published volume with access "datadir0" 70 | When I call NodeUnstageVolume 71 | Then there are no errors 72 | When I call ControllerUnpublishVolume "X_CSI_NODE_NAME" 73 | Then check Isilon client not exists "X_CSI_NODE_IP" 74 | When I call DeleteVolume 75 | Then there is not a directory "integration0" 76 | Then there is not an export "integration0" 77 | 78 | Examples: 79 | | access | 80 | | "single-writer" | 81 | | "multi-reader" | 82 | | "multi-writer" | 83 | -------------------------------------------------------------------------------- /test/integration/features/mock_different_nodeIPs.feature: -------------------------------------------------------------------------------- 1 | Feature: Isilon CSI interface 2 | As a consumer of the CSI interface 3 | I want to run a system test 4 | So that I know the service functions correctly 5 | 6 | @first_run 7 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode multi-reader 8 | Given a Isilon service 9 | And a capability with access "multi-reader" 10 | And a volume request "integration0" "8" 11 | When I call CreateVolume 12 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 13 | Then check Isilon client exists "X_CSI_NODE_NAME" 14 | When I call NodeStageVolume 15 | Then there are no errors 16 | 17 | @first_run 18 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode multi-writer 19 | Given a Isilon service 20 | And a capability with access "multi-writer" 21 | And a volume request "integration1" "8" 22 | When I call CreateVolume 23 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 24 | Then check Isilon client exists "X_CSI_NODE_NAME" 25 | When I call NodeStageVolume 26 | Then there are no errors 27 | 28 | @first_run 29 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode single-writer 30 | Given a Isilon service 31 | And a capability with access "single-writer" 32 | And a volume request "integration2" "8" 33 | When I call CreateVolume 34 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 35 | Then check Isilon client exists "X_CSI_NODE_NAME" 36 | When I call NodeStageVolume 37 | Then there are no errors 38 | 39 | @second_run 40 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode multi-reader 41 | Given a Isilon service 42 | And a capability with access "multi-reader" 43 | And a volume request "integration0" "8" 44 | When I call CreateVolume 45 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 46 | Then check Isilon client exists "X_CSI_NODE_NAME" 47 | When I call NodeStageVolume 48 | Then there are no errors 49 | When I call NodeUnstageVolume 50 | Then there are no errors 51 | When I call ControllerUnpublishVolume "X_CSI_NODE_NAME" 52 | Then check Isilon client not exists "X_CSI_NODE_NAME" 53 | When I call DeleteVolume 54 | Then there is not a directory "integration0" 55 | Then there is not an export "integration0" 56 | 57 | @second_run 58 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode multi-writer 59 | Given a Isilon service 60 | And a capability with access "multi-writer" 61 | And a volume request "integration1" "8" 62 | When I call CreateVolume 63 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 64 | Then check Isilon client exists "X_CSI_NODE_NAME" 65 | When I call NodeStageVolume 66 | Then there are no errors 67 | When I call NodeUnstageVolume 68 | Then there are no errors 69 | When I call ControllerUnpublishVolume "X_CSI_NODE_NAME" 70 | Then check Isilon client not exists "X_CSI_NODE_NAME" 71 | When I call DeleteVolume 72 | Then there is not a directory "integration1" 73 | Then there is not an export "integration1" 74 | 75 | @second_run 76 | Scenario: Create, ControllerPublish, NodeStage, NodeUnstage, ControllerUnpublish, delete basic volume with accessMode single-writer 77 | Given a Isilon service 78 | And a capability with access "single-writer" 79 | And a volume request "integration2" "8" 80 | When I call CreateVolume 81 | When I call ControllerPublishVolume "X_CSI_NODE_NAME" 82 | Then the error contains "already has other clients added to it, and the access mode is SINGLE_NODE_WRITER" 83 | When I call ControllerUnpublishVolume "X_CSI_NODE_NAME" 84 | Then check Isilon client not exists "X_CSI_NODE_NAME" 85 | When I call DeleteVolume 86 | Then there is not a directory "integration2" 87 | Then there is not an export "integration2" 88 | -------------------------------------------------------------------------------- /test/integration/kubevirt/README.md: -------------------------------------------------------------------------------- 1 | # KubeVirt Qual files for CSI PowerScale driver for OpenShift virtualization CSI certification tests 2 | 3 | Check https://confluence.cec.lab.emc.com/display/CSIECO/KubeVirt for details on running KubeVirt tests. 4 | 5 | manifest.yaml - use this file as an input to the Kubevirt test. 6 | isilon-sc.yaml - This storage class yaml is referred to by the manifest and used by the test. Ensure the Directory already exists on the array, or rename it. 7 | -------------------------------------------------------------------------------- /test/integration/kubevirt/isilon-sc.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | apiVersion: storage.k8s.io/v1 15 | kind: StorageClass 16 | metadata: 17 | name: isilon 18 | allowVolumeExpansion: true 19 | parameters: 20 | AccessZone: System 21 | # Make sure this directory exists on the array before using 22 | IsiPath: /ifs/data/qual 23 | RootClientEnabled: "true" 24 | provisioner: csi-isilon.dellemc.com 25 | reclaimPolicy: Delete 26 | volumeBindingMode: WaitForFirstConsumer 27 | -------------------------------------------------------------------------------- /test/integration/kubevirt/manifest.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | ShortName: isilon 15 | StorageClass: 16 | # Load a StorageClass from the given file. This file must be in the same directory as this one 17 | FromFile: isilon-sc.yaml 18 | 19 | SnapshotClass: 20 | # Must be set to enable snapshotting tests 21 | FromName: false 22 | 23 | DriverInfo: 24 | # Internal name of the driver, this is used as a display name in the test case and test objects 25 | Name: isilon 26 | 27 | # The range of disk size supported by this driver. Note that Min must be the EXACT size of a volume 28 | # that can be provisioned by the CSI driver. For example, when the driver requires volume sizes to be 29 | # rounded to a certain value (typically 1 or 4 GiB), Min must be rounded to that value. A test will 30 | # check that when it asks for a volume with size Min, it will get the volume with exactly that size. 31 | SupportedSizeRange: 32 | Min: 5Gi 33 | Max: 16Ti 34 | 35 | # Map of strings for supported FS types PowerScale supports nfs for sure, not sure about the others 36 | SupportedFsType: 37 | nfs: {} 38 | 39 | # Map of strings for supported mount options. This will be used to test that the CSI driver correctly 40 | # passes a mount option from Kubernetes to the kernel mount table. The mount options listed here must be: 41 | # 1. Supported by both the CSI driver and the kernel. 42 | # 2. Non-default. Note that the real set of all default mount options depends on the kernel and filesystem type. 43 | # 3. Visible in /proc/mounts after mount. 44 | # 4. Harmless, i.e., the mount option should not affect how the storage behaves too much. 45 | SupportedMountOption: 46 | noatime: {} 47 | 48 | # Optional list of topology keys that the driver supports 49 | # TopologyKeys: ["topology.ebs.csi.aws.com/zone"] 50 | TopologyKeys: 51 | 52 | # Optional number of allowed topologies that the driver requires. Only relevenat if TopologyKeys is set 53 | NumAllowedTopologies: 1 54 | 55 | # Map of strings for required mount options 56 | # RequiredMountOption: 57 | 58 | # Optional list of access modes required for provisiong. Default is RWO 59 | # RequiredAccessModes: 60 | 61 | # Map that represents the capabilities the driver supports 62 | Capabilities: 63 | # Data is persistest accross pod restarts 64 | persistence: true 65 | 66 | # Volume ownership via fsGroup 67 | fsGroup: false 68 | 69 | # Raw block mode - PowerScale does not support raw block volume 70 | block: false 71 | 72 | # Exec a file in the volume 73 | exec: true 74 | 75 | # Support for volume limits 76 | volumeLimits: false 77 | 78 | # Support for volume expansion in controllers 79 | controllerExpansion: false 80 | 81 | # Support for volume expansion in nodes 82 | nodeExpansion: false 83 | 84 | # Support volume that an run on single node only (like hostpath) 85 | singleNodeVolume: false 86 | 87 | # Support ReadWriteMany access modes (runs the mulit pod test which fails to clean up) 88 | RWX: true 89 | 90 | # Support topology 91 | topology: false 92 | 93 | # Support populate data from snapshot 94 | snapshotDataSource: false 95 | 96 | # Support populated data from PVC 97 | pvcDataSource: false 98 | -------------------------------------------------------------------------------- /test/integration/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright © 2019-2021 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | # This will run coverage analysis using the integration testing. 15 | # The env.sh must point to a valid Isilon deployment 16 | 17 | function runTest() { 18 | rm -f unix_sock 19 | source ${1} 20 | go test -v -coverprofile=c.linux.out -timeout 30m -coverpkg=../../service *test.go -args ${2} ${3} 21 | wait 22 | } 23 | 24 | echo "Quota is enabled" 25 | runTest ./env_Quota_Enabled.sh ./features/main_integration.feature "v1.0" 26 | mv ./Powerscale_integration_test_results.xml Powerscale_integration_test_results_QuotaEnabled.xml 27 | 28 | echo "Quota is not enabled" 29 | runTest ./env_Quota_notEnabled.sh ./features/integration.feature "v1.0" 30 | mv ./Powerscale_integration_test_results.xml Powerscale_integration_test_results_QuotaNotEnabled.xml 31 | 32 | echo "test accessModes with nodeIP1" 33 | runTest ./env_nodeIP1.sh ./features/mock_different_nodeIPs.feature "first_run" 34 | mv ./Powerscale_integration_test_results.xml Powerscale_integration_test_results_AccessModeIP1.xml 35 | 36 | echo "test accessModes with nodeIP2" 37 | runTest ./env_nodeIP2.sh ./features/mock_different_nodeIPs.feature "second_run" 38 | mv ./Powerscale_integration_test_results.xml Powerscale_integration_test_results_AccessModesIP2.xml 39 | 40 | echo "Custom Topology is enabled" 41 | runTest ./env_Custom_Topology_Enabled.sh ./features/integration.feature "v1.0" 42 | mv ./Powerscale_integration_test_results.xml Powerscale_integration_test_results_CustomTopology.xml 43 | -------------------------------------------------------------------------------- /test/scale_longevity/README.md: -------------------------------------------------------------------------------- 1 | # Helm charts and scripts for scalability and longevity tests 2 | 3 | This test holds a few scripts that can be used to test scalability and longevity 4 | for CSI driver 5 | 6 | ## Scalability 7 | 8 | The scaletest.sh script can be used to kick off scalability tests. 9 | This will run one series of 3 Helm deployments, causing a number of pods and replicas to be 10 | created, each with a certain number of volumes. Once the specified number of replicas have 11 | been launched, the deployments will be scaled down and removed. 12 | 13 | Log files will be created in the directory, titled `scalability-YYYYMMDD-HHMMSS.log` 14 | 15 | To launch the scalability test, a number of parameters are needed: 16 | 17 | ```sh 18 | scaletest.sh 19 | -n namespace - Namespace in which to place the test. 20 | -r replicas - Number of replicas to create 21 | -v number_volumes - Number of volumes for each pod. Default is: 1 22 | 23 | Default values for everything are set in the driver specific file at env.sh 24 | ``` 25 | 26 | An example of running the scalability tests for Isilon is: 27 | 28 | ```sh 29 | ./scaletest.sh -n test -r 33 -v 30 30 | ``` 31 | 32 | That test will deploy 3 Helm charts, with 33 replicas of each pod and 30 volumes per pod (a total of 99 pods and 2970 volumes). Once the pods are running, the system will scale down and terminate the test. 33 | 34 | ## Longevity 35 | 36 | The longevity.sh script can be used to kick off longevity tests. 37 | This will run a series of 3 Helm deployments over and over, causing a number of pods and replicas to be created and deleted until the test is stopped. To stop the test, create a file named 'stop' in the directory. Upon stopping, the deployments will be scaled down and removed. 38 | 39 | Log files will be created in the directory, titled `longevity-YYYYMMDD-HHMMSS.log` 40 | 41 | To launch the longevity test, a number of parameters are needed: 42 | 43 | ```sh 44 | longevity.sh 45 | -n namespace - Namespace in which to place the test. 46 | -r replicas - Number of replicas to create 47 | -v number_volumes - Number of volumes for each pod. Default is: 1 48 | 49 | Default values for everything are set in the driver specific file at env.sh 50 | ``` 51 | 52 | An example of running the longevity tests for Isilon is: 53 | 54 | ```sh 55 | ./longevity.sh -n test -r 10 -v 10 56 | ``` 57 | 58 | That test will deploy 3 Helm charts, with 10 replicas of each pod and 10 volumes per pod (a total of 30 pods and 300 volumes). Once the pods are running, the system will scale down to zero and repeat the process until stopped. 59 | 60 | Note that values specified on the command line override values defined in the env file. 61 | -------------------------------------------------------------------------------- /test/scale_longevity/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright © 2019 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License 13 | 14 | 15 | # Configuration file for isilon driver 16 | # This file is sourced from the longevity and scalbility test scripts 17 | # It will be executed with 'cwd' set to this directory 18 | 19 | # Longevity test helm chart 20 | LONGTEST="${LONGTEST:-volumes}" 21 | LONGREPLICAS="${LONGREPLICAS:-2}" 22 | 23 | # Scalability test helm chart 24 | SCALETEST="${SCALETEST:-volumes}" 25 | SCALEREPLICAS="${SCALEREPLICAS:-3}" 26 | 27 | # Namespace to run tests in. Will be created if it does not exist 28 | NAMESPACE="${NAMESPACE:-test}" 29 | 30 | # Storage Class names. Three of these are required but they can be the same. 31 | # These must exist before starting tests 32 | STORAGECLASS1="${STORAGECLASS1:-isilon}" 33 | STORAGECLASS2="${STORAGECLASS2:-isilon}" 34 | STORAGECLASS3="${STORAGECLASS3:-isilon}" 35 | 36 | # The namespace that the driver is running within 37 | DRIVERNAMESPACE="isilon" -------------------------------------------------------------------------------- /test/scale_longevity/volumes/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: volumes 15 | version: 1.0.0 16 | appVersion: 1.0.0 17 | description: | 18 | Test CSI Isilon deployment. 19 | keywords: 20 | - csi-isilon 21 | - storage 22 | engine: gotpl 23 | -------------------------------------------------------------------------------- /test/scale_longevity/volumes/templates/test.yaml: -------------------------------------------------------------------------------- 1 | # yamllint disable-file 2 | # This file is not valid YAML because it is a Helm template 3 | 4 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | apiVersion: apps/v1 18 | kind: StatefulSet 19 | metadata: 20 | name: {{ required "name required " .Values.name | quote }} 21 | spec: 22 | selector: 23 | matchLabels: 24 | app: csi-test 25 | serviceName: csi-test 26 | replicas: {{ required "replicas required" .Values.replicas }} 27 | podManagementPolicy: "Parallel" 28 | template: 29 | metadata: 30 | labels: 31 | app: csi-test 32 | spec: 33 | containers: 34 | - name: test 35 | image: quay.io/centos/centos:latest 36 | imagePullPolicy: IfNotPresent 37 | volumeMounts: 38 | {{ range $i, $e := until (int .Values.numberOfVolumes) }} 39 | - name: pvol-{{ $i }} 40 | mountPath: /data{{ $i }} 41 | {{ end }} 42 | command: ["/bin/bash"] 43 | args: ["-c", "trap 'exit 0' SIGTERM;while true; do sleep 1; done"] 44 | volumeClaimTemplates: 45 | {{ $storageClass := .Values.storageClass | quote }} 46 | {{ range $i, $e := until (int .Values.numberOfVolumes) }} 47 | - metadata: 48 | name: pvol-{{ $i }} 49 | spec: 50 | accessModes: [ "ReadWriteOnce" ] 51 | storageClassName: {{ required "storageClass required" $storageClass }} 52 | resources: 53 | requests: 54 | storage: 8Gi 55 | {{ end }} 56 | -------------------------------------------------------------------------------- /test/scale_longevity/volumes/values.yaml: -------------------------------------------------------------------------------- 1 | # Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | # See the License for the specific language governing permissions and 11 | # limitations under the License. 12 | # 13 | 14 | name: scaleStatefulSet 15 | replicas: 1 16 | storageClass: default 17 | numberOfVolumes: 5 18 | --------------------------------------------------------------------------------