testcontainers_modules/zitadel/
mod.rs1use std::{borrow::Cow, collections::HashMap};
2
3use testcontainers::{
4 core::{wait::HttpWaitStrategy, ContainerPort, WaitFor},
5 Image,
6};
7
8const NAME: &str = "ghcr.io/zitadel/zitadel";
9const TAG: &str = "v3.0.0-rc.2";
10const DEFAULT_MASTER_KEY: &str = "MasterkeyNeedsToHave32Characters";
11
12pub const ZITADEL_PORT: ContainerPort = ContainerPort::Tcp(8080);
17
18#[derive(Debug, Clone, Default)]
38pub struct Zitadel {
39 env_vars: HashMap<String, String>,
40}
41
42impl Zitadel {
43 fn bool_to_string(value: bool) -> String {
45 (if value { "true" } else { "false" }).to_owned()
46 }
47
48 pub fn with_external_secure(mut self, external_secure: bool) -> Self {
57 self.env_vars.insert(
58 "ZITADEL_EXTERNALSECURE".to_owned(),
59 Self::bool_to_string(external_secure),
60 );
61 self
62 }
63
64 pub fn with_postgres_database(
66 mut self,
67 host: Option<String>,
68 port: Option<u16>,
69 database: Option<String>,
70 ) -> Self {
71 match host {
72 Some(host) => self
73 .env_vars
74 .insert("ZITADEL_DATABASE_POSTGRES_HOST".to_owned(), host.to_owned()),
75 None => self.env_vars.remove("ZITADEL_DATABASE_POSTGRES_HOST"),
76 };
77 match port {
78 Some(port) => self.env_vars.insert(
79 "ZITADEL_DATABASE_POSTGRES_PORT".to_owned(),
80 port.to_string(),
81 ),
82 None => self.env_vars.remove("ZITADEL_DATABASE_POSTGRES_PORT"),
83 };
84 match database {
85 Some(database) => self.env_vars.insert(
86 "ZITADEL_DATABASE_POSTGRES_DATABASE".to_owned(),
87 database.to_owned(),
88 ),
89 None => self.env_vars.remove("ZITADEL_DATABASE_POSTGRES_DATABASE"),
90 };
91 self
92 }
93
94 pub fn with_postgres_database_user(
96 mut self,
97 username: Option<String>,
98 password: Option<String>,
99 ssl_mode: Option<String>,
100 ) -> Self {
101 match username {
102 Some(username) => self.env_vars.insert(
103 "ZITADEL_DATABASE_POSTGRES_USER_USERNAME".to_owned(),
104 username.to_owned(),
105 ),
106 None => self
107 .env_vars
108 .remove("ZITADEL_DATABASE_POSTGRES_USER_USERNAME"),
109 };
110 match password {
111 Some(password) => self.env_vars.insert(
112 "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD".to_owned(),
113 password.to_owned(),
114 ),
115 None => self
116 .env_vars
117 .remove("ZITADEL_DATABASE_POSTGRES_USER_PASSWORD"),
118 };
119 match ssl_mode {
120 Some(ssl_mode) => self.env_vars.insert(
121 "ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE".to_owned(),
122 ssl_mode.to_owned(),
123 ),
124 None => self
125 .env_vars
126 .remove("ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE"),
127 };
128 self
129 }
130
131 pub fn with_postgres_database_admin(
133 mut self,
134 username: Option<String>,
135 password: Option<String>,
136 ssl_mode: Option<String>,
137 ) -> Self {
138 match username {
139 Some(username) => self.env_vars.insert(
140 "ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME".to_owned(),
141 username.to_owned(),
142 ),
143 None => self
144 .env_vars
145 .remove("ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME"),
146 };
147 match password {
148 Some(password) => self.env_vars.insert(
149 "ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD".to_owned(),
150 password.to_owned(),
151 ),
152 None => self
153 .env_vars
154 .remove("ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD"),
155 };
156 match ssl_mode {
157 Some(ssl_mode) => self.env_vars.insert(
158 "ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE".to_owned(),
159 ssl_mode.to_owned(),
160 ),
161 None => self
162 .env_vars
163 .remove("ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE"),
164 };
165 self
166 }
167}
168
169impl Image for Zitadel {
170 fn name(&self) -> &str {
171 NAME
172 }
173
174 fn tag(&self) -> &str {
175 TAG
176 }
177
178 fn ready_conditions(&self) -> Vec<WaitFor> {
179 vec![
180 WaitFor::message_on_stderr("server is listening on"),
181 WaitFor::http(
182 HttpWaitStrategy::new("/debug/healthz")
183 .with_port(ZITADEL_PORT)
184 .with_expected_status_code(200_u16)
185 .with_body("ok".as_bytes()),
186 ),
187 ]
188 }
189
190 fn env_vars(
191 &self,
192 ) -> impl IntoIterator<Item = (impl Into<Cow<'_, str>>, impl Into<Cow<'_, str>>)> {
193 &self.env_vars
194 }
195
196 fn cmd(&self) -> impl IntoIterator<Item = impl Into<Cow<'_, str>>> {
197 [
198 "start-from-init",
199 "--masterkey",
200 DEFAULT_MASTER_KEY,
201 "--tlsMode",
202 "disabled",
203 ]
204 }
205
206 fn expose_ports(&self) -> &[ContainerPort] {
207 &[ZITADEL_PORT]
208 }
209}