Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
nikoshet committed Oct 18, 2024
1 parent 0aadb96 commit 556b6b5
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 89 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,26 @@ jobs:
format-and-clippy:
uses: ./.github/workflows/format-workflow.yaml
secrets: inherit
tests:
uses: ./.github/workflows/tests-workflow.yaml
secrets: inherit
build:
runs-on: ubuntu-latest
needs: [format-and-clippy]
needs: [format-and-clippy, tests]
strategy:
fail-fast: true
matrix:
include:
- name: "library"
path: "."
- name: "client"
path: "pvc-snapshotter-client"
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
toolchain: ${{ env.RUST_VERSION }}
- name: Build
- name: Cargo Build ${{ matrix.name }}
run: cargo build --verbose
working-directory: ${{ matrix.path }}
24 changes: 24 additions & 0 deletions .github/workflows/tests-workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Tests Pipeline

on:
workflow_call:

env:
RUST_VERSION: 1.81.0

jobs:
tests:
name: Run Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
toolchain: ${{ env.RUST_VERSION }}
- name: Install cargo-nextest
uses: baptiste0928/cargo-install@v3
with:
crate: cargo-nextest
- name: Run tests
run: cargo nextest run --all
72 changes: 72 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tokio = { version = "1", features = ["full"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
pvc-snapshotter = { path = ".", version = "0.1" }
mockall = "0.13"

[dependencies]
anyhow.workspace = true
Expand All @@ -50,6 +51,7 @@ serde_json.workspace = true
tokio.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
mockall.workspace = true

[lib]
test = true
Expand Down
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ The tool supports three primary modes of operation:
Restore: Restore PVCs from existing snapshots.
Full: Run both backup and restore operations in a single process.


<br>
> [!NOTE]
> Average percentage of time saved by PVC-Snapshotter compared to [Velero](https://github.com/vmware-tanzu/velero): **X%**.
<br>
## Features
- **Backup**: Create Kubernetes VolumeSnapshots from existing PVCs
- **Restore**: Restore PVCs to any namespace from a VolumeSnapshot
Expand Down
1 change: 1 addition & 0 deletions pvc-snapshotter-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ tokio.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
pvc-snapshotter.workspace = true
mockall = "0.13.0"

[features]
default = ["full"]
Expand Down
15 changes: 9 additions & 6 deletions src/backup/backup_operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use super::backup_payload::BackupPayload;
use crate::{
aws_ops::ebs::create_ebs_client,
k8s_ops::{
pvc::persistent_volume_claims::{check_if_pvc_exists, get_pvcs_available},
vs::volume_snapshots::wait_untill_snapshot_is_ready,
vs::volume_snapshots_operator::VolumeSnapshotOperator,
pvc::persistent_volume_claims::{check_if_pvc_exists, get_pvcs_available, KubePvcApi},
vs::{
volume_snapshots::wait_untill_snapshot_is_ready,
volume_snapshots_operator::VolumeSnapshotOperator,
},
vsc::retain_policy::VSCRetainPolicy,
},
};
use anyhow::{bail, Result};
use k8s_openapi::api::core::v1::PersistentVolumeClaim;
use kube::{api::PostParams, Api, Client};
use kube_custom_resources_rs::snapshot_storage_k8s_io::v1::{
volumesnapshotcontents::VolumeSnapshotContent,
Expand All @@ -34,7 +35,9 @@ impl BackupOperator {
// Define the VolumeSnapshot and VolumeSnapshotContent APIs
let restore_k8s_apis_struct = BackupKubernetesApisStruct {
source_vs_api: Api::namespaced(k8s_client.clone(), backup_payload.source_ns()),
source_pvcs_api: Api::namespaced(k8s_client.clone(), backup_payload.source_ns()),
source_pvcs_api: KubePvcApi {
api: Api::namespaced(k8s_client.clone(), backup_payload.source_ns()),
},
vsc_api: Api::all(k8s_client.clone()),
};

Expand Down Expand Up @@ -102,6 +105,6 @@ impl BackupOperator {
/// A struct for holding the Kubernetes APIs for the backup operation
struct BackupKubernetesApisStruct {
source_vs_api: Api<VolumeSnapshot>,
source_pvcs_api: Api<PersistentVolumeClaim>,
source_pvcs_api: KubePvcApi,
vsc_api: Api<VolumeSnapshotContent>,
}
54 changes: 46 additions & 8 deletions src/k8s_ops/pvc/persistent_volume_claims.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,51 @@
use anyhow::Result;
use async_trait::async_trait;
use k8s_openapi::api::core::v1::PersistentVolumeClaim;
use kube::api::ListParams;
use kube::{api::ListParams, Api};
use tracing::info;

#[cfg(test)]
use mockall::automock;

#[cfg_attr(test, automock)]
#[async_trait]
pub trait PvcApiTrait {
async fn list_pvcs(&self) -> Result<Vec<PersistentVolumeClaim>>;
async fn get(&self, name: &str) -> Result<PersistentVolumeClaim>;
async fn create(&self, pvc: PersistentVolumeClaim) -> Result<PersistentVolumeClaim>;
}

pub struct KubePvcApi {
pub api: Api<PersistentVolumeClaim>,
}

/// Implement the PvcApi trait for PVC Api
/// This will allow us to call the functions defined in the PvcApi trait on an instance of KubePvcApi.
/// This is useful for testing, as we can mock the KubePvcApi struct and implement the PvcApi trait
/// to return mock data.
/// This way, we can test the functions that use the KubePvcApi struct without actually making
/// calls to the Kubernetes API.
#[async_trait]
impl PvcApiTrait for KubePvcApi {
async fn list_pvcs(&self) -> Result<Vec<PersistentVolumeClaim>> {
let pvcs = self.api.list(&ListParams::default()).await?;
Ok(pvcs.items)
}

async fn get(&self, name: &str) -> Result<PersistentVolumeClaim> {
let pvc = self.api.get(name).await?;
Ok(pvc)
}

async fn create(&self, pvc: PersistentVolumeClaim) -> Result<PersistentVolumeClaim> {
let pvc = self.api.create(&Default::default(), &pvc).await?;
Ok(pvc)
}
}

/// Get the list of PersistentVolumeClaims available
pub async fn get_pvcs_available(
target_pvc_api: &kube::Api<PersistentVolumeClaim>,
) -> Result<Vec<String>> {
let lp = ListParams::default();
let pvc_list: Vec<_> = match target_pvc_api.list(&lp).await {
pub async fn get_pvcs_available(pvc_api: &impl PvcApiTrait) -> Result<Vec<String>> {
let pvc_list: Vec<_> = match pvc_api.list_pvcs().await {
Ok(pvc) => pvc,
Err(e) => panic!("Failed to list PVCs: {}", e),
}
Expand All @@ -20,7 +57,8 @@ pub async fn get_pvcs_available(
}

pub async fn check_if_pvc_exists(
target_pvc_api: &kube::Api<PersistentVolumeClaim>,
target_pvc_api: &impl PvcApiTrait,
//&kube::Api<PersistentVolumeClaim>,
pvc_name: &str,
should_exist: bool,
) -> Result<Option<PersistentVolumeClaim>> {
Expand All @@ -38,7 +76,7 @@ pub async fn check_if_pvc_exists(
Ok(Some(pvc))
} else {
panic!(
"PVC exists: {} on target namespace {:?}",
"PVC does not exist: {} on target namespace {:?}",
pvc.metadata.name.clone().unwrap(),
pvc.metadata.namespace.clone().unwrap()
);
Expand Down
Loading

0 comments on commit 556b6b5

Please sign in to comment.