@@ -9,6 +9,7 @@ use stackable_operator::{
99 crd:: authentication:: oidc,
1010 k8s_openapi:: api:: core:: v1:: Secret ,
1111 kube:: { ResourceExt , runtime:: reflector:: ObjectRef } ,
12+ kvp:: ObjectLabels ,
1213} ;
1314
1415use crate :: { crd:: v1alpha1, security:: authentication:: STACKABLE_ADMIN_USERNAME } ;
@@ -37,64 +38,70 @@ pub enum Error {
3738
3839 #[ snafu( display( "Nifi doesn't support skipping the OIDC TLS verification" ) ) ]
3940 SkippingTlsVerificationNotSupported { } ,
41+
42+ #[ snafu( display( "failed to build OIDC admin password secret metadata" ) ) ]
43+ BuildOidcAdminPasswordSecretMetadata {
44+ source : stackable_operator:: builder:: meta:: Error ,
45+ } ,
4046}
4147
42- /// Generate a secret containing the password for the admin user that can access the API .
48+ /// Build a Secret containing the OIDC admin password .
4349///
44- /// This admin user is the same as for SingleUser authentication.
45- pub ( crate ) async fn check_or_generate_oidc_admin_password (
50+ /// If the secret already exists, the existing password is preserved.
51+ /// Otherwise a new random password is generated.
52+ pub ( crate ) async fn build_oidc_admin_password_secret (
4653 client : & Client ,
4754 nifi : & v1alpha1:: NifiCluster ,
48- ) -> Result < bool , Error > {
55+ labels : ObjectLabels < ' _ , v1alpha1:: NifiCluster > ,
56+ ) -> Result < Secret , Error > {
4957 let namespace: & str = & nifi. namespace ( ) . context ( ObjectHasNoNamespaceSnafu ) ?;
5058 tracing:: debug!( "Checking for OIDC admin password configuration" ) ;
51- match client
59+
60+ let password = match client
5261 . get_opt :: < Secret > ( & build_oidc_admin_password_secret_name ( nifi) , namespace)
5362 . await
5463 . context ( OidcAdminPasswordSecretSnafu ) ?
5564 {
5665 Some ( secret) => {
57- let admin_password_present = secret
66+ let existing_password = secret
5867 . data
59- . iter ( )
60- . flat_map ( |data| data. keys ( ) )
61- . any ( |key| key == STACKABLE_ADMIN_USERNAME ) ;
62-
63- if admin_password_present {
64- Ok ( false )
65- } else {
66- MissingAdminPasswordKeySnafu {
68+ . as_ref ( )
69+ . and_then ( |data| data. get ( STACKABLE_ADMIN_USERNAME ) )
70+ . map ( |bytes| String :: from_utf8_lossy ( & bytes. 0 ) . into_owned ( ) ) ;
71+
72+ match existing_password {
73+ Some ( password) => password,
74+ None => MissingAdminPasswordKeySnafu {
6775 secret : ObjectRef :: from_obj ( & secret) ,
6876 }
69- . fail ( ) ?
77+ . fail ( ) ?,
7078 }
7179 }
7280 None => {
73- tracing:: info!( "No existing oidc admin password secret found, generating new one" ) ;
74- let password : String = rand:: rng ( )
81+ tracing:: info!( "No existing OIDC admin password secret found, generating new one" ) ;
82+ rand:: rng ( )
7583 . sample_iter ( & Alphanumeric )
7684 . take ( 15 )
7785 . map ( char:: from)
78- . collect ( ) ;
79-
80- let mut secret_data = BTreeMap :: new ( ) ;
81- secret_data. insert ( "admin" . to_string ( ) , password) ;
82-
83- let new_secret = Secret {
84- metadata : ObjectMetaBuilder :: new ( )
85- . namespace ( namespace)
86- . name ( build_oidc_admin_password_secret_name ( nifi) )
87- . build ( ) ,
88- string_data : Some ( secret_data) ,
89- ..Secret :: default ( )
90- } ;
91- client
92- . create ( & new_secret)
93- . await
94- . context ( OidcAdminPasswordSecretSnafu ) ?;
95- Ok ( true )
86+ . collect ( )
9687 }
97- }
88+ } ;
89+
90+ Ok ( Secret {
91+ metadata : ObjectMetaBuilder :: new ( )
92+ . name_and_namespace ( nifi)
93+ . name ( build_oidc_admin_password_secret_name ( nifi) )
94+ . ownerreference_from_resource ( nifi, None , Some ( true ) )
95+ . context ( BuildOidcAdminPasswordSecretMetadataSnafu ) ?
96+ . with_recommended_labels ( labels)
97+ . context ( BuildOidcAdminPasswordSecretMetadataSnafu ) ?
98+ . build ( ) ,
99+ string_data : Some ( BTreeMap :: from ( [ (
100+ STACKABLE_ADMIN_USERNAME . to_string ( ) ,
101+ password,
102+ ) ] ) ) ,
103+ ..Secret :: default ( )
104+ } )
98105}
99106
100107pub fn build_oidc_admin_password_secret_name ( nifi : & v1alpha1:: NifiCluster ) -> String {
0 commit comments