-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(volume): don't allow unpublish from non-frontend node #889
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -323,6 +323,8 @@ message UnpublishVolumeRequest { | |||||
// the nexus. Note: this option should be used only when we know the node will not become | ||||||
// accessible again and it is safe to do so. | ||||||
bool force = 2; | ||||||
// frontend host requesting for volume unpublish. | ||||||
optional string frontend_host = 3; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In-keeping with publish
Suggested change
|
||||||
} | ||||||
|
||||||
// Share Volume request | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1618,6 +1618,8 @@ pub trait UnpublishVolumeInfo: Send + Sync + std::fmt::Debug { | |||||
fn uuid(&self) -> VolumeId; | ||||||
/// Force unpublish | ||||||
fn force(&self) -> bool; | ||||||
/// Frontend node requesting unpublish. | ||||||
fn frontend_host(&self) -> Option<NodeId>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
impl UnpublishVolumeInfo for UnpublishVolume { | ||||||
|
@@ -1628,6 +1630,10 @@ impl UnpublishVolumeInfo for UnpublishVolume { | |||||
fn force(&self) -> bool { | ||||||
self.force() | ||||||
} | ||||||
|
||||||
fn frontend_host(&self) -> Option<NodeId> { | ||||||
self.frontend_host().clone() | ||||||
} | ||||||
} | ||||||
|
||||||
/// Intermediate structure that validates the conversion to UnpublishVolumeRequest type. | ||||||
|
@@ -1644,6 +1650,13 @@ impl UnpublishVolumeInfo for ValidatedUnpublishVolumeRequest { | |||||
fn force(&self) -> bool { | ||||||
self.inner.force | ||||||
} | ||||||
|
||||||
fn frontend_host(&self) -> Option<NodeId> { | ||||||
self.inner | ||||||
.frontend_host | ||||||
.clone() | ||||||
.map(|target_node| target_node.into()) | ||||||
} | ||||||
} | ||||||
|
||||||
impl ValidateRequestTypes for UnpublishVolumeRequest { | ||||||
|
@@ -1658,7 +1671,7 @@ impl ValidateRequestTypes for UnpublishVolumeRequest { | |||||
|
||||||
impl From<&dyn UnpublishVolumeInfo> for UnpublishVolume { | ||||||
fn from(data: &dyn UnpublishVolumeInfo) -> Self { | ||||||
UnpublishVolume::new(&data.uuid(), data.force()) | ||||||
UnpublishVolume::new(&data.uuid(), data.force(), data.frontend_host()) | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -1667,6 +1680,7 @@ impl From<&dyn UnpublishVolumeInfo> for UnpublishVolumeRequest { | |||||
Self { | ||||||
uuid: Some(data.uuid().to_string()), | ||||||
force: data.force(), | ||||||
frontend_host: data.frontend_host().map(|n| n.into()), | ||||||
} | ||||||
} | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,4 +112,10 @@ Scenario: list existing volumes with pagination max entries set to 0 | |
Given 2 existing volumes | ||
When a ListVolumesRequest is sent to CSI controller with max_entries set to 0 | ||
Then all volumes should be returned | ||
And the next token should be empty | ||
And the next token should be empty | ||
|
||
Scenario: unpublish volume from non-frontend node | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should cover the returned errors when the nodes don't match |
||
Given a 2 replica volume published on a node | ||
When the ControllerUnpublishVolume request arrives from a non-frontend node | ||
Then nvmf target which exposes the volume should not be destroyed | ||
And volume should remain as published |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this feels somewhat wrong, what if target was not deleted because of some other precondition error.
Maybe we need a different error here that is clearer? Something more similar to NOT_FOUND perhaps? Given that the target is not available for this node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
NotAcceptable
? I intended to do that earlierThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that seems good. wdyt @Abhinandan-Purkait ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Although there is one more mapping of not acceptable but looking at other options this sounds reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also use the error body for additional info if we need to do additional mapping