kanidmd/
opt.rs

1#[derive(Debug, Args)]
2struct CommonOpt {
3    /// Path to the server's configuration file.
4    #[clap(short, long = "config", env = "KANIDM_CONFIG")]
5    config_path: Option<PathBuf>,
6    /// Log format (still in very early development)
7    #[clap(short, long = "output", env = "KANIDM_OUTPUT", default_value = "text")]
8    output_mode: String,
9}
10
11#[derive(Debug, Args)]
12struct BackupOpt {
13    #[clap(value_parser)]
14    /// Output path for the backup content.
15    path: PathBuf,
16    #[clap(flatten)]
17    commonopts: CommonOpt,
18}
19
20#[derive(Debug, Args)]
21struct RestoreOpt {
22    #[clap(value_parser)]
23    /// Restore from this path. Should be created with "backup".
24    path: PathBuf,
25    #[clap(flatten)]
26    commonopts: CommonOpt,
27}
28
29#[derive(Debug, Subcommand)]
30enum DomainSettingsCmds {
31    /// Show the current domain
32    #[clap(name = "show")]
33    Show {
34        #[clap(flatten)]
35        commonopts: CommonOpt,
36    },
37    /// Change the IDM domain name based on the values in the configuration
38    #[clap(name = "rename")]
39    Change {
40        #[clap(flatten)]
41        commonopts: CommonOpt,
42    },
43    /// Perform a pre-upgrade-check of this domains content. This will report possible
44    /// incompatibilities that can block a successful upgrade to the next version of
45    /// Kanidm. This is a safe read only operation.
46    #[clap(name = "upgrade-check")]
47    UpgradeCheck {
48        #[clap(flatten)]
49        commonopts: CommonOpt,
50    },
51    /// ⚠️  Do not use this command unless directed by a project member. ⚠️ 
52    /// - Raise the functional level of this domain to the maximum available.
53    #[clap(name = "raise")]
54    Raise {
55        #[clap(flatten)]
56        commonopts: CommonOpt,
57    },
58    /// ⚠️  Do not use this command unless directed by a project member. ⚠️ 
59    /// - Rerun migrations of this domains database, optionally nominating the level
60    ///   to start from.
61    #[clap(name = "remigrate")]
62    Remigrate {
63        #[clap(flatten)]
64        commonopts: CommonOpt,
65        level: Option<u32>,
66    },
67}
68
69#[derive(Debug, Subcommand)]
70enum DbCommands {
71    #[clap(name = "vacuum")]
72    /// Vacuum the database to reclaim space or change db_fs_type/page_size (offline)
73    Vacuum(CommonOpt),
74    #[clap(name = "backup")]
75    /// Backup the database content (offline)
76    Backup(BackupOpt),
77    #[clap(name = "restore")]
78    /// Restore the database content (offline)
79    Restore(RestoreOpt),
80    #[clap(name = "verify")]
81    /// Verify database and entity consistency.
82    Verify(CommonOpt),
83    #[clap(name = "reindex")]
84    /// Reindex the database (offline)
85    Reindex(CommonOpt),
86}
87
88#[derive(Debug, Args)]
89struct DbScanListIndex {
90    /// The name of the index to list
91    index_name: String,
92    #[clap(flatten)]
93    commonopts: CommonOpt,
94}
95
96#[derive(Debug, Parser)]
97struct HealthCheckArgs {
98    /// Disable TLS verification
99    #[clap(short, long, action)]
100    verify_tls: bool,
101    /// Check the 'origin' URL from the server configuration file, instead of the 'address'
102    #[clap(short = 'O', long, action)]
103    check_origin: bool,
104    #[clap(flatten)]
105    commonopts: CommonOpt,
106}
107
108#[derive(Debug, Args)]
109struct DbScanGetId2Entry {
110    /// The id of the entry to display
111    id: u64,
112    #[clap(flatten)]
113    commonopts: CommonOpt,
114}
115
116#[derive(Debug, Subcommand)]
117enum DbScanOpt {
118    #[clap(name = "list-all-indexes")]
119    /// List all index tables that exist on the system.
120    ListIndexes(CommonOpt),
121    #[clap(name = "list-index")]
122    /// List all content of a named index
123    ListIndex(DbScanListIndex),
124    // #[structopt(name = "get_index")]
125    // /// Display the content of a single index key
126    // GetIndex(DbScanGetIndex),
127    #[clap(name = "list-id2entry")]
128    /// List all id2entry values with reduced entry content
129    ListId2Entry(CommonOpt),
130    #[clap(name = "get-id2entry")]
131    /// View the data of a specific entry from id2entry
132    GetId2Entry(DbScanGetId2Entry),
133    #[clap(name = "list-index-analysis")]
134    /// List all content of index analysis
135    ListIndexAnalysis(CommonOpt),
136    #[clap(name = "quarantine-id2entry")]
137    /// Given an entry id, quarantine the entry in a hidden db partition
138    QuarantineId2Entry {
139        /// The id of the entry to display
140        id: u64,
141        #[clap(flatten)]
142        commonopts: CommonOpt,
143    },
144    #[clap(name = "list-quarantined")]
145    /// List the entries in quarantine
146    ListQuarantined {
147        #[clap(flatten)]
148        commonopts: CommonOpt,
149    },
150    #[clap(name = "restore-quarantined")]
151    /// Given an entry id, restore the entry from the hidden db partition
152    RestoreQuarantined {
153        /// The id of the entry to display
154        id: u64,
155        #[clap(flatten)]
156        commonopts: CommonOpt,
157    },
158}
159
160#[derive(Debug, Parser)]
161#[command(name = "kanidmd")]
162struct KanidmdParser {
163    #[command(subcommand)]
164    commands: KanidmdOpt,
165}
166
167impl KanidmdParser {
168    /// Returns the configuration path that was specified on the command line, if any.
169    fn config_path(&self) -> Option<PathBuf> {
170        match self.commands {
171            KanidmdOpt::Server(ref c) => c.config_path.clone(),
172            KanidmdOpt::ConfigTest(ref c) => c.config_path.clone(),
173            KanidmdOpt::CertGenerate(ref c) => c.config_path.clone(),
174            KanidmdOpt::RecoverAccount { ref commonopts, .. } => commonopts.config_path.clone(),
175            KanidmdOpt::ShowReplicationCertificate { ref commonopts, .. } => {
176                commonopts.config_path.clone()
177            }
178            KanidmdOpt::RenewReplicationCertificate { ref commonopts, .. } => {
179                commonopts.config_path.clone()
180            }
181            KanidmdOpt::RefreshReplicationConsumer { ref commonopts, .. } => {
182                commonopts.config_path.clone()
183            }
184            KanidmdOpt::DbScan { ref commands } => match commands {
185                DbScanOpt::ListIndexes(ref c) => c.config_path.clone(),
186                DbScanOpt::ListIndex(ref c) => c.commonopts.config_path.clone(),
187                DbScanOpt::ListId2Entry(ref c) => c.config_path.clone(),
188                DbScanOpt::GetId2Entry(ref c) => c.commonopts.config_path.clone(),
189                DbScanOpt::ListIndexAnalysis(ref c) => c.config_path.clone(),
190                DbScanOpt::QuarantineId2Entry { ref commonopts, .. } => {
191                    commonopts.config_path.clone()
192                }
193                DbScanOpt::ListQuarantined { ref commonopts } => commonopts.config_path.clone(),
194                DbScanOpt::RestoreQuarantined { ref commonopts, .. } => {
195                    commonopts.config_path.clone()
196                }
197            },
198            KanidmdOpt::Database { ref commands } => match commands {
199                DbCommands::Vacuum(ref c) => c.config_path.clone(),
200                DbCommands::Backup(ref c) => c.commonopts.config_path.clone(),
201                DbCommands::Restore(ref c) => c.commonopts.config_path.clone(),
202                DbCommands::Verify(ref c) => c.config_path.clone(),
203                DbCommands::Reindex(ref c) => c.config_path.clone(),
204            },
205            KanidmdOpt::DomainSettings { ref commands } => match commands {
206                DomainSettingsCmds::Show { ref commonopts } => commonopts.config_path.clone(),
207                DomainSettingsCmds::Change { ref commonopts } => commonopts.config_path.clone(),
208                DomainSettingsCmds::UpgradeCheck { ref commonopts } => commonopts.config_path.clone(),
209                DomainSettingsCmds::Raise { ref commonopts } => commonopts.config_path.clone(),
210                DomainSettingsCmds::Remigrate { ref commonopts, .. } => {
211                    commonopts.config_path.clone()
212                }
213            },
214            KanidmdOpt::HealthCheck(ref c) => c.commonopts.config_path.clone(),
215            KanidmdOpt::Version(ref c) => c.config_path.clone(),
216        }
217    }
218}
219
220#[derive(Debug, Subcommand)]
221enum KanidmdOpt {
222    #[clap(name = "server")]
223    /// Start the IDM Server
224    Server(CommonOpt),
225    #[clap(name = "configtest")]
226    /// Test the IDM Server configuration, without starting network listeners.
227    ConfigTest(CommonOpt),
228    #[clap(name = "cert-generate")]
229    /// Create a self-signed ca and tls certificate in the locations listed from the
230    /// configuration. These certificates should *not* be used in production, they
231    /// are for testing and evaluation only!
232    CertGenerate(CommonOpt),
233    #[clap(name = "recover-account")]
234    /// Recover an account's password
235    RecoverAccount {
236        #[clap(value_parser)]
237        /// The account name to recover credentials for.
238        name: String,
239        #[clap(flatten)]
240        commonopts: CommonOpt,
241    },
242    /// Display this server's replication certificate
243    ShowReplicationCertificate {
244        #[clap(flatten)]
245        commonopts: CommonOpt,
246    },
247    /// Renew this server's replication certificate
248    RenewReplicationCertificate {
249        #[clap(flatten)]
250        commonopts: CommonOpt,
251    },
252    /// Refresh this servers database content with the content from a supplier. This means
253    /// that all local content will be deleted and replaced with the supplier content.
254    RefreshReplicationConsumer {
255        #[clap(flatten)]
256        commonopts: CommonOpt,
257        /// Acknowledge that this database content will be refreshed from a supplier.
258        #[clap(long = "i-want-to-refresh-this-servers-database")]
259        proceed: bool,
260    },
261    // #[clap(name = "reset_server_id")]
262    // ResetServerId(CommonOpt),
263    #[clap(name = "db-scan")]
264    /// Inspect the internal content of the database datastructures.
265    DbScan {
266        #[clap(subcommand)]
267        commands: DbScanOpt,
268    },
269    /// Database maintenance, backups, restoration etc.
270    #[clap(name = "database")]
271    Database {
272        #[clap(subcommand)]
273        commands: DbCommands,
274    },
275    /// Change domain settings
276    #[clap(name = "domain")]
277    DomainSettings {
278        #[clap(subcommand)]
279        commands: DomainSettingsCmds,
280    },
281
282    /// Load the server config and check services are listening
283    #[clap(name = "healthcheck")]
284    HealthCheck(HealthCheckArgs),
285
286    /// Print the program version and exit
287    #[clap(name = "version")]
288    Version(CommonOpt),
289}