Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Mk.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
build_system: cargo
env:
RUST_LOG: rustcloak_operator=debug,reqwest=trace,warn
#RUST_LOG: debug
Expand Down
26 changes: 13 additions & 13 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ resolver = "2"
members = ["rustcloak-operator", "rustcloak-crd", "utils"]

[workspace.package]
version = "0.3.2"
version = "0.4.0"
authors = [
"Enno Boland <mail@eboland.de>",
]
repository = "https://github.com/DenktMit-eG/rustcloak-operator"
readme = "README.md"
license = "AGPL-3.0"
license = "BSD-2-Clause"
edition = "2024"

[workspace.dependencies]
Expand Down
4 changes: 2 additions & 2 deletions charts/rustcloak-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ maintainers:
- name: Enno Boland
email: mail@eboland.de
url: https://github.com/Gottox
version: 0.3.2
appVersion: "v0.3.2"
version: 0.4.0
appVersion: "v0.4.0"
2 changes: 1 addition & 1 deletion charts/rustcloak-operator/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# rustcloak-operator

![Version: 0.3.2](https://img.shields.io/badge/Version-0.3.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.3.2](https://img.shields.io/badge/AppVersion-v0.3.2-informational?style=flat-square)
![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.4.0](https://img.shields.io/badge/AppVersion-v0.4.0-informational?style=flat-square)

The helm-chart for the rustcloak-operator

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ spec:
create:
nullable: true
type: boolean
namespace:
description: The namespace where the secret is located. Will only be used for ClusterKeycloakInstance.
nullable: true
type: string
passwordKey:
nullable: true
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ spec:
create:
nullable: true
type: boolean
namespace:
description: The namespace where the secret is located. Will only be used for ClusterKeycloakInstance.
nullable: true
type: string
passwordKey:
nullable: true
type: string
Expand Down
1 change: 0 additions & 1 deletion docs/book.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[book]
authors = ["Enno Boland"]
language = "en"
multilingual = false
src = "src"
title = "Rustcloak Operator"

Expand Down
10 changes: 10 additions & 0 deletions docs/src/crds/clusterkeycloakinstance.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This resource makes a Keycloak instance known to the operator
|[spec.client.secret](#specclientsecret)|string||
|[spec.credentials](#speccredentials)|object|✅|
|[spec.credentials.create](#speccredentialscreate)|boolean||
|[spec.credentials.namespace](#speccredentialsnamespace)|string||
|[spec.credentials.passwordKey](#speccredentialspasswordkey)|string||
|[spec.credentials.secretName](#speccredentialssecretname)|string|✅|
|[spec.credentials.usernameKey](#speccredentialsusernamekey)|string||
Expand Down Expand Up @@ -101,6 +102,7 @@ Type: object
|Property|Type|Required|
|:-------|:---|:------:|
|[create](#speccredentialscreate)|boolean||
|[namespace](#speccredentialsnamespace)|string||
|[passwordKey](#speccredentialspasswordkey)|string||
|[secretName](#speccredentialssecretname)|string|✅|
|[usernameKey](#speccredentialsusernamekey)|string||
Expand All @@ -117,6 +119,14 @@ Type: boolean

---

### spec.credentials.namespace

Type: string

The namespace where the secret is located. Will only be used for ClusterKeycloakInstance.

---

### spec.credentials.passwordKey

Type: string
Expand Down
10 changes: 10 additions & 0 deletions docs/src/crds/keycloakinstance.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This resource makes a Keycloak instance known to the operator
|[spec.client.secret](#specclientsecret)|string||
|[spec.credentials](#speccredentials)|object|✅|
|[spec.credentials.create](#speccredentialscreate)|boolean||
|[spec.credentials.namespace](#speccredentialsnamespace)|string||
|[spec.credentials.passwordKey](#speccredentialspasswordkey)|string||
|[spec.credentials.secretName](#speccredentialssecretname)|string|✅|
|[spec.credentials.usernameKey](#speccredentialsusernamekey)|string||
Expand Down Expand Up @@ -101,6 +102,7 @@ Type: object
|Property|Type|Required|
|:-------|:---|:------:|
|[create](#speccredentialscreate)|boolean||
|[namespace](#speccredentialsnamespace)|string||
|[passwordKey](#speccredentialspasswordkey)|string||
|[secretName](#speccredentialssecretname)|string|✅|
|[usernameKey](#speccredentialsusernamekey)|string||
Expand All @@ -117,6 +119,14 @@ Type: boolean

---

### spec.credentials.namespace

Type: string

The namespace where the secret is located. Will only be used for ClusterKeycloakInstance.

---

### spec.credentials.passwordKey

Type: string
Expand Down
2 changes: 2 additions & 0 deletions rustcloak-crd/src/crd/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use serde::{Deserialize, Serialize};
pub struct KeycloakInstanceCredentialReference {
pub create: Option<bool>,
pub secret_name: String,
/// The namespace where the secret is located. Will only be used for ClusterKeycloakInstance.
pub namespace: Option<String>,
pub username_key: Option<String>,
pub password_key: Option<String>,
}
Expand Down
3 changes: 2 additions & 1 deletion rustcloak-operator/src/bin/rustcloak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use rustcloak_operator::{
fn init_logger() {
use structured_logger::{Builder, async_json::new_writer};

Builder::with_level("info")
let level = structured_logger::get_env_level();
Builder::with_level(level.as_str())
.with_target_writer("*", new_writer(tokio::io::stdout()))
.init();
}
Expand Down
13 changes: 11 additions & 2 deletions rustcloak-operator/src/controller/instance_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use kube::{
core::object::HasStatus,
runtime::{Controller, controller::Action, watcher},
};
use log::debug;
use randstr::randstr;
use rustcloak_crd::{
KeycloakApiStatus,
Expand Down Expand Up @@ -78,14 +79,22 @@ impl<R> InstanceController<R>
where
R: Instance,
{
fn secret_namespace(resource: &R) -> Option<String> {
let spec = resource.inner_spec();
if let Some(ns) = resource.namespace() {
Some(ns)
} else {
spec.credentials.namespace.clone()
}
}
async fn create_secret(
&self,
client: &kube::Client,
resource: Arc<R>,
) -> Result<()> {
let spec = resource.inner_spec();
let secret_name = &spec.credentials.secret_name;
let ns = resource.namespace();
let ns = Self::secret_namespace(&resource);
let secret_api = ApiExt::<Secret>::api(client.clone(), &ns);
let [username_key, password_key] = spec.credentials.secret_key_names();

Expand All @@ -109,7 +118,6 @@ where
data: Some(data),
metadata: ObjectMeta {
name: Some(secret_name.to_string()),
namespace: ns,
owner_references: Some(vec![owner_ref]),
..Default::default()
},
Expand Down Expand Up @@ -173,6 +181,7 @@ where
resource: Arc<Self::Resource>,
) -> Result<bool> {
let spec = resource.inner_spec();
debug!("Scheduling refresh for resource {}", resource.name_any());
match self
.manager
.schedule_refresh(&resource, client.clone())
Expand Down
1 change: 1 addition & 0 deletions rustcloak-operator/src/controller/legacy/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl LifecycleController for LegacyInstanceController {
secret_name: format!("credential-{}", &name),
username_key: Some("ADMIN_USERNAME".to_string()),
password_key: Some("ADMIN_PASSWORD".to_string()),
namespace: None,
},
token: None,
client: None,
Expand Down
25 changes: 19 additions & 6 deletions rustcloak-operator/src/util/k8s_keycloak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use kube::{
runtime::reflector::ObjectRef,
};
use log::{debug, warn};
use rustcloak_crd::{instance::KeycloakInstance, traits::SecretKeyNames};
use rustcloak_crd::{
instance::KeycloakInstance,
traits::SecretKeyNames,
};
use std::{
borrow::Cow,
collections::{BTreeMap, HashMap},
Expand All @@ -32,6 +35,18 @@ use tokio::{

use super::SecretUtils;

fn secret_namespace<R>(resource: &R) -> Option<String>
where
R: Instance,
{
let spec = resource.inner_spec();
if let Some(ns) = resource.namespace() {
Some(ns)
} else {
spec.credentials.namespace.clone()
}
}

fn token_into_secret<R: Instance>(
oauth2_token: &OAuth2Token,
instance: &R,
Expand All @@ -45,7 +60,6 @@ fn token_into_secret<R: Instance>(
.map(|x| ByteString(x.to_rfc3339().into_bytes()));
let name = spec.token_secret_name(&name);
let [token_key, expires_key] = spec.token.secret_key_names();
let ns = instance.namespace();
let owner_ref = instance.owner_ref(&()).unwrap();
let mut data: BTreeMap<String, ByteString> =
[(token_key.to_string(), token)].into();
Expand All @@ -55,7 +69,6 @@ fn token_into_secret<R: Instance>(
Ok(Secret {
metadata: ObjectMeta {
name: Some(name),
namespace: ns,
owner_references: Some(vec![owner_ref]),
..Default::default()
},
Expand Down Expand Up @@ -115,7 +128,7 @@ impl<'a> K8sKeycloakBuilder<'a> {

pub async fn with_credentials(self) -> Result<ApiClient> {
let spec = &self.instance.spec;
let ns = self.instance.namespace();
let ns = secret_namespace(&self.instance);
let kind = &self.kind;
let secret_api = ApiExt::<Secret>::api(self.client.clone(), &ns);
let credential_secret_name = spec.credential_secret_name().to_string();
Expand All @@ -141,7 +154,7 @@ impl<'a> K8sKeycloakBuilder<'a> {
pub async fn with_token(self) -> Result<ApiClient> {
let spec = &self.instance.spec;
let name = self.instance.name_unchecked();
let ns = self.instance.namespace();
let ns = secret_namespace(&self.instance);
let kind = &self.kind;
let secret_api = ApiExt::<Secret>::api(self.client.clone(), &ns);
let token_secret_name = spec.token_secret_name(&name).to_string();
Expand Down Expand Up @@ -186,7 +199,7 @@ impl<R: Instance> K8sKeycloakRefreshJob<R> {
}

pub async fn update_token_secret(&self, token: &OAuth2Token) -> Result<()> {
let ns = self.instance.namespace();
let ns = secret_namespace(self.instance.deref());
let api = ApiExt::<Secret>::api(self.client.clone(), &ns);
let token_secret = token_into_secret(token, self.instance.deref())?;
api.patch(
Expand Down
Loading