@@ -5,6 +5,7 @@ use serde;
55use std:: fmt;
66
77pub mod templates;
8+ pub mod example_values;
89
910#[ derive( serde:: Serialize ) ]
1011pub struct init_vars {
@@ -14,18 +15,18 @@ pub struct init_vars {
1415 pub registry_build_pass : String ,
1516 pub registry_cluster_user : String ,
1617 pub registry_cluster_pass : String ,
17- pub defaults_difficulty : String , //u64,
18- pub defaults_resources_cpu : String , //u64,
19- pub defaults_resources_memory : String , //(u64, Option(String)),
18+ pub defaults_difficulty : String ,
19+ pub defaults_resources_cpu : String ,
20+ pub defaults_resources_memory : String ,
2021 pub points : Vec < points > ,
2122 pub profiles : Vec < profile > ,
2223}
2324
2425#[ derive( Clone , serde:: Serialize ) ]
2526pub struct points {
26- pub difficulty : String , //u64,
27- pub min : String , //u64,
28- pub max : String , //u64
27+ pub difficulty : String ,
28+ pub min : String ,
29+ pub max : String ,
2930}
3031
3132impl fmt:: Display for points {
@@ -63,43 +64,47 @@ pub fn interactive_init() -> inquire::error::InquireResult<init_vars> {
6364 //TODO:
6465 // - also provide regex examples in help
6566 // - is this even a good idea to have the user provide the regex
66- // - with placeholder?
67+ // - what kind of regex is being validated and accepted
6768 inquire:: Text :: new ( "Flag regex:" )
6869 . with_help_message ( "This regex will be used to validate the individual flags of your challenges later." )
70+ . with_placeholder ( example_values:: FLAG_REGEX )
6971 . prompt ( ) ?
7072 } ,
7173
7274 registry_domain : {
7375 inquire:: Text :: new ( "Container registry:" )
74- . with_help_message ( "This is the domain of your remote container registry, which includes both the endpoint details and your repository name." ) //where you will push images to and where your cluster will pull challenge images from.") // TODO
76+ . with_help_message ( "Hosted challenges will be hosted in a container registry.The connection endpoint and the repository name." )
77+ . with_placeholder ( example_values:: REGISTRY_DOMAIN )
7578 . prompt ( ) ?
7679 } ,
7780
7881 registry_build_user : {
79- inquire:: Text :: new ( "Container registry user (YOURS):" )
80- . with_help_message ( "Your username to the remote container registry, which you will use to push containers to." )
82+ inquire:: Text :: new ( "Container registry 'build' user:" )
83+ . with_help_message ( "The username that will be used to push built containers." )
84+ . with_placeholder ( example_values:: REGISTRY_BUILD_USER )
8185 . prompt ( ) ?
8286 } ,
8387
8488 // TODO: do we actually want to be in charge of these credentials vs letting the container building utility take care of it?
8589 registry_build_pass : {
86- inquire:: Password :: new ( "Container registry password (YOURS) :" )
87- . with_help_message ( "Your password to the remote container registry, which you will use to push containers to. " ) // TODO: could this support username:pat too?
90+ inquire:: Password :: new ( "Container registry 'build' password :" )
91+ . with_help_message ( "The password to the 'build' user account " ) // TODO: could this support username:pat too?
8892 . with_display_mode ( inquire:: PasswordDisplayMode :: Masked )
8993 . with_custom_confirmation_message ( "Enter again:" )
9094 . prompt ( ) ?
9195 } ,
9296
9397 registry_cluster_user : {
94- inquire:: Text :: new ( "Container registry user (CLUSTER'S):" )
95- . with_help_message ( "The cluster's username to the remote container registry, which it will use to pull containers from." )
98+ inquire:: Text :: new ( "Container registry 'cluster' user:" )
99+ . with_help_message ( "The username that the cluster will use to pull locally-built containers." )
100+ . with_placeholder ( example_values:: REGISTRY_CLUSTER_USER )
96101 . prompt ( ) ?
97102 } ,
98103
99104 // TODO: would the cluster not use a token of some sort?
100105 registry_cluster_pass : {
101- inquire:: Password :: new ( "Container registry password (CLUSTER'S) :" )
102- . with_help_message ( "The cluster's password to the remote container registry, which it will use to pull containers from. " )
106+ inquire:: Password :: new ( "Container registry 'cluster' password :" )
107+ . with_help_message ( "The password to the 'cluster' user account " )
103108 . with_display_mode ( inquire:: PasswordDisplayMode :: Masked )
104109 . with_custom_confirmation_message ( "Enter again:" )
105110 . prompt ( ) ?
@@ -119,23 +124,26 @@ pub fn interactive_init() -> inquire::error::InquireResult<init_vars> {
119124 // default parser calls std::u64::from_str
120125 . with_error_message ( "Please type a valid number." )
121126 . with_help_message ( "The rank of the difficulty class as an unsigned integer, with lower numbers being \" easier.\" " )
127+ . with_placeholder ( example_values:: POINTS_DIFFICULTY )
122128 . prompt ( ) ?
123129 . to_string ( )
124130 } ,
125131 // TODO: support static-point challenges
126132 min : {
127- inquire:: CustomType :: < u64 > :: new ( "Minimum number of points:" )
133+ inquire:: CustomType :: < u64 > :: new ( "Minimum points:" )
128134 // default parser calls std::u64::from_str
129135 . with_error_message ( "Please type a valid number." )
130- . with_help_message ( "Challenge points are dynamic: the minimum number of points that challenges within this difficulty class are worth." )
136+ . with_help_message ( "Challenge points are dynamic. The minimum number of points that challenges within this difficulty class are worth." )
137+ . with_placeholder ( example_values:: POINTS_MIN )
131138 . prompt ( ) ?
132139 . to_string ( )
133140 } ,
134141 max : {
135- inquire:: CustomType :: < u64 > :: new ( "Maximum number of points:" )
142+ inquire:: CustomType :: < u64 > :: new ( "Maximum points:" )
136143 // default parser calls std::u64::from_str
137144 . with_error_message ( "Please type a valid number." )
138- . with_help_message ( "Challenge points are dynamic: the maximum number of points that challenges within this difficulty class are worth." )
145+ . with_help_message ( "The maximum number of points that challenges within this difficulty class are worth." )
146+ . with_placeholder ( example_values:: POINTS_MAX )
139147 . prompt ( ) ?
140148 . to_string ( )
141149 } ,
@@ -150,7 +158,6 @@ pub fn interactive_init() -> inquire::error::InquireResult<init_vars> {
150158 points_ranks
151159 } ,
152160
153- // TODO: how much format validation should these two do now vs offloading to validate() later? current inquire replacement calls are temporary and do the zero checking, just grabbing a String
154161 defaults_difficulty : {
155162 if points_ranks_reference. is_empty ( ) {
156163 String :: new ( )
@@ -165,26 +172,26 @@ pub fn interactive_init() -> inquire::error::InquireResult<init_vars> {
165172 } ,
166173
167174 defaults_resources_cpu : {
168- let resources = inquire:: Text :: new ( "Default limit of CPUs per challenge :" )
169- . with_help_message ( "The maximum limit of CPU resources per instance of challenge deployment ( \" pod\" ). " )
170- . with_placeholder ( "1" )
175+ let resources = inquire:: Text :: new ( "Default CPU limit :" )
176+ . with_help_message ( "The default limit of CPU resources per challenge pod. \n https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes " )
177+ . with_placeholder ( example_values :: DEFAULTS_RESOURCES_CPU )
171178 . prompt ( ) ?;
172179
173180 if resources. is_empty ( ) {
174- String :: from ( "1" )
181+ String :: from ( example_values :: DEFAULTS_RESOURCES_CPU )
175182 } else {
176183 resources
177184 }
178185 } ,
179186
180187 defaults_resources_memory : {
181- let resources = inquire:: Text :: new ( "Default limit of memory per challenge :" )
182- . with_help_message ( "The maximum limit of memory resources per instance of challenge deployment ( \" pod\" ). " )
183- . with_placeholder ( "500M" )
188+ let resources = inquire:: Text :: new ( "Default memory limit :" )
189+ . with_help_message ( "The default limit of CPU resources per challenge pod. \n https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes " )
190+ . with_placeholder ( example_values :: DEFAULTS_RESOURCES_MEMORY )
184191 . prompt ( ) ?;
185192
186193 if resources. is_empty ( ) {
187- String :: from ( "500M" )
194+ String :: from ( example_values :: DEFAULTS_RESOURCES_MEMORY )
188195 } else {
189196 resources
190197 }
@@ -202,54 +209,63 @@ pub fn interactive_init() -> inquire::error::InquireResult<init_vars> {
202209 profile_name : {
203210 inquire:: Text :: new ( "Profile name:" )
204211 . with_help_message ( "The name of the deployment profile. One profile named \" default\" is recommended. You can add additional profiles." )
205- . with_placeholder ( "default" )
212+ . with_placeholder ( example_values :: PROFILES_PROFILE_NAME )
206213 . prompt ( ) ?
207214 } ,
208215 frontend_url : {
209216 inquire:: Text :: new ( "Frontend URL:" )
210- . with_help_message ( "The URL of the RNG scoreboard." ) // TODO: can definitely say more about why this is significant
217+ . with_help_message ( "The URL of the RNG scoreboard." )
218+ . with_placeholder ( example_values:: PROFILES_FRONTEND_URL )
211219 . prompt ( ) ?
212220 } ,
213221 frontend_token : {
214222 inquire:: Text :: new ( "Frontend token:" )
215223 . with_help_message (
216- "The token for RNG to authenticate itself into the scoreboard." ,
217- ) // TODO: again, say more
224+ "The token to authenticate into the RNG scoreboard." ,
225+ )
226+ . with_placeholder ( example_values:: PROFILES_FRONTEND_TOKEN )
218227 . prompt ( ) ?
219228 } ,
220229 challenges_domain : {
221230 inquire:: Text :: new ( "Challenges domain:" )
222231 . with_help_message ( "Domain that challenges are hosted under." )
232+ . with_placeholder ( example_values:: PROFILES_CHALLENGES_DOMAIN )
223233 . prompt ( ) ?
224234 } ,
225235 kubecontext : {
226- inquire:: Text :: new ( "Kube context:" )
227- . with_help_message ( "The name of the context that kubectl looks for to interface with the cluster." )
236+ inquire:: Text :: new ( "Kubecontext name:" )
237+ . with_help_message ( "The name of the context that kubectl uses to connect to the cluster." )
238+ . with_placeholder ( example_values:: PROFILES_KUBECONTEXT )
228239 . prompt ( ) ?
229240 } ,
230241 s3_bucket_name : {
231242 inquire:: Text :: new ( "S3 bucket name:" )
232- . with_help_message ( "Challenge artifacts and static files will be hosted on and served from S3. The name of the S3 bucket." )
243+ . with_help_message ( "Challenge artifacts and static files will be hosted on S3. The name of the S3 bucket." )
244+ . with_placeholder ( example_values:: PROFILES_S3_BUCKET_NAME )
233245 . prompt ( ) ?
234246 } ,
235247 s3_endpoint : {
236248 inquire:: Text :: new ( "S3 endpoint:" )
237249 . with_help_message ( "The endpoint of the S3 bucket server." )
250+ . with_placeholder ( example_values:: PROFILES_S3_ENDPOINT )
238251 . prompt ( ) ?
239252 } ,
240253 s3_region : {
241254 inquire:: Text :: new ( "S3 region:" )
242- . with_help_message ( "The region that the S3 bucket is hosted." )
255+ . with_help_message ( "The region where the S3 bucket is hosted." )
256+ . with_placeholder ( example_values:: PROFILES_S3_REGION )
243257 . prompt ( ) ?
244258 } ,
245259 s3_accesskey : {
246260 inquire:: Text :: new ( "S3 access key:" )
247261 . with_help_message ( "The public access key to the S3 bucket." )
262+ . with_placeholder ( example_values:: PROFILES_S3_ACCESSKEY )
248263 . prompt ( ) ?
249264 } ,
250265 s3_secretaccesskey : {
251266 inquire:: Text :: new ( "S3 secret key:" )
252267 . with_help_message ( "The secret acess key to the S3 bucket." )
268+ . with_placeholder ( example_values:: PROFILES_S3_SECRETACCESSKEY )
253269 . prompt ( ) ?
254270 } ,
255271 } ;
@@ -282,7 +298,7 @@ pub fn blank_init() -> init_vars {
282298 max: String :: new( ) ,
283299 } ] ,
284300 profiles : vec ! [ profile {
285- profile_name: String :: from( "default" ) ,
301+ profile_name: String :: from( example_values :: PROFILES_PROFILE_NAME ) ,
286302 frontend_url: String :: new( ) ,
287303 frontend_token: String :: new( ) ,
288304 challenges_domain: String :: new( ) ,
@@ -298,38 +314,38 @@ pub fn blank_init() -> init_vars {
298314
299315pub fn example_init ( ) -> init_vars {
300316 return init_vars {
301- flag_regex : String :: from ( "ctf{.*}" ) , // TODO: do that wildcard in the most common regex flavor since Rust regex supports multiple styles
302- registry_domain : String :: from ( "ghcr.io/youraccount" ) ,
303- registry_build_user : String :: from ( "admin" ) ,
304- registry_build_pass : String :: from ( "notrealcreds" ) ,
305- registry_cluster_user : String :: from ( "cluster_user" ) ,
306- registry_cluster_pass : String :: from ( "alsofake" ) ,
307- defaults_difficulty : String :: from ( "1" ) ,
308- defaults_resources_cpu : String :: from ( "1" ) ,
309- defaults_resources_memory : String :: from ( "500M" ) ,
317+ flag_regex : String :: from ( example_values :: FLAG_REGEX ) , // TODO: do that wildcard in the most common regex flavor since Rust regex supports multiple styles
318+ registry_domain : String :: from ( example_values :: REGISTRY_DOMAIN ) ,
319+ registry_build_user : String :: from ( example_values :: REGISTRY_BUILD_USER ) ,
320+ registry_build_pass : String :: from ( example_values :: REGISTRY_BUILD_PASS ) ,
321+ registry_cluster_user : String :: from ( example_values :: REGISTRY_CLUSTER_USER ) ,
322+ registry_cluster_pass : String :: from ( example_values :: REGISTRY_CLUSTER_USER ) ,
323+ defaults_difficulty : String :: from ( example_values :: DEFAULTS_DIFFICULTY ) ,
324+ defaults_resources_cpu : String :: from ( example_values :: DEFAULTS_RESOURCES_CPU ) ,
325+ defaults_resources_memory : String :: from ( example_values :: DEFAULTS_RESOURCES_MEMORY ) ,
310326 points : vec ! [
311327 points {
312- difficulty: String :: from( "1" ) ,
313- min: String :: from( "1" ) ,
314- max: String :: from( "1337" ) ,
328+ difficulty: String :: from( example_values :: POINTS_DIFFICULTY ) ,
329+ min: String :: from( example_values :: POINTS_MIN ) ,
330+ max: String :: from( example_values :: POINTS_MAX ) ,
315331 } ,
316332 points {
317333 difficulty: String :: from( "2" ) ,
318- min: String :: from( "200 " ) ,
319- max: String :: from( "500 " ) ,
334+ min: String :: from( "1 " ) ,
335+ max: String :: from( "1337 " ) ,
320336 } ,
321337 ] ,
322338 profiles : vec ! [ profile {
323- profile_name: String :: from( "default" ) ,
324- frontend_url: String :: from( "https://ctf.coolguy.invalid" ) ,
325- frontend_token: String :: from( "secretsecretsecret" ) ,
326- challenges_domain: String :: from( "chals.coolguy.invalid" ) ,
327- kubecontext: String :: from( "ctf-cluster" ) ,
328- s3_bucket_name: String :: from( "ctf-bucket" ) ,
329- s3_endpoint: String :: from( "s3.coolguy.invalid" ) ,
330- s3_region: String :: from( "us-west-2" ) ,
331- s3_accesskey: String :: from( "accesskey" ) ,
332- s3_secretaccesskey: String :: from( "secretkey" ) ,
339+ profile_name: String :: from( example_values :: PROFILES_PROFILE_NAME ) ,
340+ frontend_url: String :: from( example_values :: PROFILES_FRONTEND_URL ) ,
341+ frontend_token: String :: from( example_values :: PROFILES_FRONTEND_TOKEN ) ,
342+ challenges_domain: String :: from( example_values :: PROFILES_CHALLENGES_DOMAIN ) ,
343+ kubecontext: String :: from( example_values :: PROFILES_KUBECONTEXT ) ,
344+ s3_bucket_name: String :: from( example_values :: PROFILES_S3_BUCKET_NAME ) ,
345+ s3_endpoint: String :: from( example_values :: PROFILES_S3_ENDPOINT ) ,
346+ s3_region: String :: from( example_values :: PROFILES_S3_REGION ) ,
347+ s3_accesskey: String :: from( example_values :: PROFILES_S3_ACCESSKEY ) ,
348+ s3_secretaccesskey: String :: from( example_values :: PROFILES_S3_SECRETACCESSKEY ) ,
333349 } ] ,
334350 } ;
335351}
0 commit comments