mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Added orca flag to extend privileged authentication expiry (#2949)
This commit is contained in:
parent
3ae8453375
commit
12f297e526
|
@ -53,8 +53,11 @@ pub async fn populate(_client: &KanidmOrcaClient, profile: Profile) -> Result<St
|
|||
|
||||
let thread_count = profile.thread_count();
|
||||
|
||||
// PHASE 0 - For now, set require MFA off.
|
||||
let preflight_flags = vec![Flag::DisableAllPersonsMFAPolicy];
|
||||
// PHASE 0 - For now, set require MFA off and extend the privilege expiry.
|
||||
let preflight_flags = vec![
|
||||
Flag::DisableAllPersonsMFAPolicy,
|
||||
Flag::ExtendPrivilegedAuthExpiry,
|
||||
];
|
||||
|
||||
// PHASE 1 - generate a pool of persons that are not-yet created for future import.
|
||||
|
||||
|
|
|
@ -64,6 +64,24 @@ impl KanidmOrcaClient {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn extend_privilege_expiry(&self) -> Result<(), Error> {
|
||||
self.idm_admin_client
|
||||
.group_account_policy_privilege_expiry_set("idm_all_persons", 3600)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!(?err, "Unable to modify idm_all_persons policy");
|
||||
Error::KanidmClient
|
||||
})?;
|
||||
|
||||
self.idm_admin_client
|
||||
.group_account_policy_privilege_expiry_set("idm_all_accounts", 3600)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!(?err, "Unable to modify idm_all_accounts policy");
|
||||
Error::KanidmClient
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn person_exists(&self, username: &str) -> Result<bool, Error> {
|
||||
self.idm_admin_client
|
||||
.idm_person_account_get(username)
|
||||
|
|
|
@ -77,6 +77,7 @@ fn main() -> ExitCode {
|
|||
profile_path,
|
||||
threads,
|
||||
model,
|
||||
dump_raw_data,
|
||||
} => {
|
||||
// For now I hardcoded some dimensions, but we should prompt
|
||||
// the user for these later.
|
||||
|
@ -98,6 +99,7 @@ fn main() -> ExitCode {
|
|||
idm_admin_password,
|
||||
model,
|
||||
threads,
|
||||
dump_raw_data,
|
||||
)
|
||||
.seed(seed);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ impl Transition {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum TransitionResult {
|
||||
// Success
|
||||
Ok,
|
||||
|
|
|
@ -70,6 +70,10 @@ pub enum OrcaOpt {
|
|||
#[clap(long, default_value_t, value_enum)]
|
||||
// Optional model to run the benchmark, defaults to the `Basic` model
|
||||
model: Model,
|
||||
|
||||
#[clap(long, default_value_t)]
|
||||
/// Dump raw data to a separate csv file, defaults to false
|
||||
dump_raw_data: bool,
|
||||
},
|
||||
|
||||
#[clap(name = "conntest")]
|
||||
|
|
|
@ -12,6 +12,7 @@ async fn apply_flags(client: Arc<kani::KanidmOrcaClient>, flags: &[Flag]) -> Res
|
|||
for flag in flags {
|
||||
match flag {
|
||||
Flag::DisableAllPersonsMFAPolicy => client.disable_mfa_requirement().await?,
|
||||
Flag::ExtendPrivilegedAuthExpiry => client.extend_privilege_expiry().await?,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -36,6 +36,8 @@ pub struct Profile {
|
|||
thread_count: Option<usize>,
|
||||
model: Model,
|
||||
group: BTreeMap<String, GroupProperties>,
|
||||
#[serde(default)]
|
||||
dump_raw_data: bool,
|
||||
}
|
||||
|
||||
impl Profile {
|
||||
|
@ -91,6 +93,10 @@ impl Profile {
|
|||
pub fn test_time(&self) -> Option<Duration> {
|
||||
self.test_time.map(Duration::from_secs)
|
||||
}
|
||||
|
||||
pub fn dump_raw_data(&self) -> bool {
|
||||
self.dump_raw_data
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProfileBuilder {
|
||||
|
@ -106,6 +112,7 @@ pub struct ProfileBuilder {
|
|||
pub person_count: Option<u64>,
|
||||
pub thread_count: Option<usize>,
|
||||
pub model: Model,
|
||||
pub dump_raw_data: bool,
|
||||
}
|
||||
|
||||
fn validate_u64_bound(value: Option<u64>, default: u64) -> Result<u64, Error> {
|
||||
|
@ -129,6 +136,7 @@ impl ProfileBuilder {
|
|||
idm_admin_password: String,
|
||||
model: Model,
|
||||
thread_count: Option<usize>,
|
||||
dump_raw_data: bool,
|
||||
) -> Self {
|
||||
ProfileBuilder {
|
||||
control_uri,
|
||||
|
@ -142,6 +150,7 @@ impl ProfileBuilder {
|
|||
person_count: None,
|
||||
thread_count,
|
||||
model,
|
||||
dump_raw_data,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +196,7 @@ impl ProfileBuilder {
|
|||
person_count,
|
||||
thread_count,
|
||||
model,
|
||||
dump_raw_data,
|
||||
} = self;
|
||||
|
||||
let seed: u64 = seed.unwrap_or_else(|| {
|
||||
|
@ -224,6 +234,7 @@ impl ProfileBuilder {
|
|||
thread_count,
|
||||
group,
|
||||
model,
|
||||
dump_raw_data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use crossbeam::queue::{ArrayQueue, SegQueue};
|
|||
|
||||
use kanidm_client::{KanidmClient, KanidmClientBuilder};
|
||||
|
||||
use serde::Serialize;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
|
@ -48,7 +49,7 @@ pub struct EventRecord {
|
|||
pub details: EventDetail,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
pub enum EventDetail {
|
||||
Login,
|
||||
Logout,
|
||||
|
@ -145,8 +146,11 @@ pub async fn execute(state: State, control_rx: broadcast::Receiver<Signal>) -> R
|
|||
let mut dyn_data_collector =
|
||||
BasicStatistics::new(state.persons.len(), state.groups.len(), node_count);
|
||||
|
||||
let stats_task =
|
||||
tokio::task::spawn_blocking(move || dyn_data_collector.run(c_stats_queue, c_stats_ctrl));
|
||||
let dump_raw_data = state.profile.dump_raw_data();
|
||||
|
||||
let stats_task = tokio::task::spawn_blocking(move || {
|
||||
dyn_data_collector.run(c_stats_queue, c_stats_ctrl, dump_raw_data)
|
||||
});
|
||||
|
||||
// Create clients. Note, we actually seed these deterministically too, so that
|
||||
// or persons are spread over the clients that exist, in a way that is also
|
||||
|
|
|
@ -58,6 +58,7 @@ impl TryFrom<&Path> for State {
|
|||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum Flag {
|
||||
DisableAllPersonsMFAPolicy,
|
||||
ExtendPrivilegedAuthExpiry,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Serialize, Deserialize)]
|
||||
|
|
|
@ -22,6 +22,7 @@ pub trait DataCollector {
|
|||
&mut self,
|
||||
stats_queue: Arc<SegQueue<EventRecord>>,
|
||||
ctrl: Arc<ArrayQueue<TestPhase>>,
|
||||
dump_raw_data: bool,
|
||||
) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
|
@ -30,6 +31,7 @@ enum OpKind {
|
|||
ReadOp,
|
||||
ReplicationDelay,
|
||||
Auth, //TODO! does this make sense?
|
||||
Error,
|
||||
}
|
||||
|
||||
impl From<EventDetail> for OpKind {
|
||||
|
@ -42,11 +44,9 @@ impl From<EventDetail> for OpKind {
|
|||
| EventDetail::PersonSetSelfPassword
|
||||
| EventDetail::PersonCreateGroup
|
||||
| EventDetail::PersonAddGroupMembers => OpKind::WriteOp,
|
||||
EventDetail::Error
|
||||
| EventDetail::Login
|
||||
| EventDetail::Logout
|
||||
| EventDetail::PersonReauth => OpKind::Auth,
|
||||
EventDetail::Login | EventDetail::Logout | EventDetail::PersonReauth => OpKind::Auth,
|
||||
EventDetail::GroupReplicationDelay => OpKind::ReplicationDelay,
|
||||
EventDetail::Error => OpKind::Error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ impl DataCollector for BasicStatistics {
|
|||
&mut self,
|
||||
stats_queue: Arc<SegQueue<EventRecord>>,
|
||||
ctrl: Arc<ArrayQueue<TestPhase>>,
|
||||
dump_raw_data: bool,
|
||||
) -> Result<(), Error> {
|
||||
debug!("Started statistics collector");
|
||||
|
||||
|
@ -123,6 +124,7 @@ impl DataCollector for BasicStatistics {
|
|||
let mut readop_times = Vec::new();
|
||||
let mut writeop_times = Vec::new();
|
||||
let mut replication_delays = Vec::new();
|
||||
let mut raw_stats = Vec::new();
|
||||
|
||||
// We will drain this now.
|
||||
while let Some(event_record) = stats_queue.pop() {
|
||||
|
@ -131,6 +133,13 @@ impl DataCollector for BasicStatistics {
|
|||
continue;
|
||||
}
|
||||
|
||||
if dump_raw_data {
|
||||
raw_stats.push(SerializableEventRecord::from_event_record(
|
||||
&event_record,
|
||||
start,
|
||||
));
|
||||
}
|
||||
|
||||
match OpKind::from(event_record.details) {
|
||||
OpKind::ReadOp => {
|
||||
readop_times.push(event_record.duration.as_secs_f64());
|
||||
|
@ -142,6 +151,7 @@ impl DataCollector for BasicStatistics {
|
|||
replication_delays.push(event_record.duration.as_secs_f64())
|
||||
}
|
||||
OpKind::Auth => {}
|
||||
OpKind::Error => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,12 +206,40 @@ impl DataCollector for BasicStatistics {
|
|||
let mut wrt = Writer::from_path(filepath).map_err(|_| Error::Io)?;
|
||||
wrt.serialize(stats).map_err(|_| Error::Io)?;
|
||||
|
||||
if dump_raw_data {
|
||||
let raw_data_filepath = format!("orca-run-{}-raw.csv", now.to_rfc3339());
|
||||
info!("Now saving raw data as '{raw_data_filepath}'");
|
||||
|
||||
let mut wrt = Writer::from_path(raw_data_filepath).map_err(|_| Error::Io)?;
|
||||
|
||||
for record in raw_stats.iter() {
|
||||
wrt.serialize(record).map_err(|_| Error::Io)?;
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Ended statistics collector");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SerializableEventRecord {
|
||||
time_from_start_ms: u128,
|
||||
duration_ms: u128,
|
||||
details: EventDetail,
|
||||
}
|
||||
|
||||
impl SerializableEventRecord {
|
||||
fn from_event_record(event_record: &EventRecord, test_start: Instant) -> Self {
|
||||
SerializableEventRecord {
|
||||
time_from_start_ms: event_record.start.duration_since(test_start).as_millis(),
|
||||
duration_ms: event_record.duration.as_millis(),
|
||||
details: event_record.details.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct StatsContainer {
|
||||
node_count: usize,
|
||||
|
|
Loading…
Reference in a new issue