-
Notifications
You must be signed in to change notification settings - Fork 28
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
Implement updates of deployment when echo changes #33
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
use std::sync::Arc; | ||
|
||
use futures::stream::StreamExt; | ||
use k8s_openapi::api::apps::v1::Deployment; | ||
use kube::runtime::watcher::Config; | ||
use kube::Resource; | ||
use kube::ResourceExt; | ||
|
@@ -69,6 +70,8 @@ enum EchoAction { | |
Create, | ||
/// Delete all subresources created in the `Create` phase | ||
Delete, | ||
/// Update existing subresources to match the desired state | ||
Update, | ||
/// This `Echo` resource is in desired state and requires no actions to be taken | ||
NoOp, | ||
} | ||
|
@@ -94,7 +97,7 @@ async fn reconcile(echo: Arc<Echo>, context: Arc<ContextData>) -> Result<Action, | |
let name = echo.name_any(); // Name of the Echo resource is used to name the subresources as well. | ||
|
||
// Performs action as decided by the `determine_action` function. | ||
return match determine_action(&echo) { | ||
match determine_action(context.client.clone(), &echo).await? { | ||
EchoAction::Create => { | ||
// Creates a deployment with `n` Echo service pods, but applies a finalizer first. | ||
// Finalizer is applied first, as the operator might be shut down and restarted | ||
|
@@ -108,6 +111,7 @@ async fn reconcile(echo: Arc<Echo>, context: Arc<ContextData>) -> Result<Action, | |
echo::deploy(client, &name, echo.spec.replicas, &namespace).await?; | ||
Ok(Action::requeue(Duration::from_secs(10))) | ||
} | ||
|
||
EchoAction::Delete => { | ||
// Deletes any subresources related to this `Echo` resources. If and only if all subresources | ||
// are deleted, the finalizer is removed and Kubernetes is free to remove the `Echo` resource. | ||
|
@@ -123,9 +127,16 @@ async fn reconcile(echo: Arc<Echo>, context: Arc<ContextData>) -> Result<Action, | |
finalizer::delete(client, &name, &namespace).await?; | ||
Ok(Action::await_change()) // Makes no sense to delete after a successful delete, as the resource is gone | ||
} | ||
|
||
EchoAction::Update => { | ||
// Update the deployment to match the desired state | ||
echo::update(client, &name, echo.spec.replicas, &namespace).await?; | ||
Ok(Action::requeue(Duration::from_secs(10))) | ||
} | ||
|
||
// The resource is already in desired state, do nothing and re-check after 10 seconds | ||
EchoAction::NoOp => Ok(Action::requeue(Duration::from_secs(10))), | ||
}; | ||
} | ||
} | ||
|
||
/// Resources arrives into reconciliation queue in a certain state. This function looks at | ||
|
@@ -134,19 +145,33 @@ async fn reconcile(echo: Arc<Echo>, context: Arc<ContextData>) -> Result<Action, | |
/// | ||
/// # Arguments | ||
/// - `echo`: A reference to `Echo` being reconciled to decide next action upon. | ||
fn determine_action(echo: &Echo) -> EchoAction { | ||
return if echo.meta().deletion_timestamp.is_some() { | ||
EchoAction::Delete | ||
async fn determine_action(client: Client, echo: &Echo) -> Result<EchoAction, Error> { | ||
if echo.meta().deletion_timestamp.is_some() { | ||
Ok(EchoAction::Delete) | ||
} else if echo | ||
.meta() | ||
.finalizers | ||
.as_ref() | ||
.map_or(true, |finalizers| finalizers.is_empty()) | ||
{ | ||
EchoAction::Create | ||
Ok(EchoAction::Create) | ||
} else { | ||
EchoAction::NoOp | ||
}; | ||
let deployment_api: Api<Deployment> = Api::namespaced( | ||
client, | ||
echo.meta() | ||
.namespace | ||
.as_ref() | ||
.expect("expected namespace to be set"), | ||
); | ||
|
||
let deployment = deployment_api.get(&echo.name_any()).await?; | ||
|
||
if deployment.spec.expect("expected spec to be set").replicas != Some(echo.spec.replicas) { | ||
Ok(EchoAction::Update) | ||
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. There's a difference between patch and update, as described e.g. here https://kubernetes.io/docs/reference/using-api/api-concepts/#patch-and-apply The action is named update, yet it performs a patch. |
||
} else { | ||
Ok(EchoAction::NoOp) | ||
} | ||
} | ||
} | ||
|
||
/// Actions to be taken when a reconciliation fails - for whatever reason. | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 repository contains a minimalistic custom resource, with one field only. Even in this case, the kubernetes API should be allowed to handle the diff, not the application code. Kubernetes itself compares the resources using resource version (update) or checks for conflicts (patch).
The patched resource should simply be serialized and sent in an HTTP Patch request, and let Kubernetes handle the rest. Checking parts of the resource locally would be a bad practice in general. Between the version comparison and the HTTP request, yet another change to the resource can be applied.
https://kubernetes.io/docs/reference/using-api/api-concepts/#patch-and-apply