@@ -217,52 +217,62 @@ func buildServiceListCmd() *cobra.Command {
217217// serviceCreateCmd represents the create command under service
218218func buildServiceCreateCmd () * cobra.Command {
219219 var createServiceName string
220- var createServiceType string
220+ var createAddons [] string
221221 var createRegionCode string
222222 var createCpuMillis int
223- var createMemoryGbs float64
223+ var createMemoryGbs int
224224 var createReplicaCount int
225225 var createNoWait bool
226226 var createWaitTimeout time.Duration
227227 var createNoSetDefault bool
228+ var createFree bool
228229
229230 cmd := & cobra.Command {
230231 Use : "create" ,
231232 Short : "Create a new database service" ,
232233 Long : `Create a new database service in the current project.
233234
234- By default, the newly created service will be set as your default service for future
235+ By default, the newly created service will be set as your default service for future
235236commands. Use --no-set-default to prevent this behavior.
236237
237238Examples:
238239 # Create a TimescaleDB service with all defaults (0.5 CPU, 2GB, us-east-1, auto-generated name)
239240 tiger service create
240-
241- # Create a TimescaleDB service with custom name
242- tiger service create --name my-db
243241
244- # Create a PostgreSQL service with more resources (waits for ready by default)
245- tiger service create --name prod-db --type postgres --cpu 2000 --memory 8 --replicas 2
242+ # Create a free TimescaleDB service
243+ tiger service create --name free-db --free
244+
245+ # Create a TimescaleDB service with AI add-ons
246+ tiger service create --name hybrid-db --addons time-series,ai
247+
248+ # Create a plain Postgres service
249+ tiger service create --name postgres-db --addons none
250+
251+ # Create a service with more resources (waits for ready by default)
252+ tiger service create --name resources-db --cpu 2000 --memory 8 --replicas 2
246253
247254 # Create service in a different region
248- tiger service create --name eu-db --region google-europe-west1
255+ tiger service create --name eu-db --region eu-central-1
249256
250257 # Create service without setting it as default
251258 tiger service create --name temp-db --no-set-default
252259
253260 # Create service specifying only CPU (memory will be auto-configured to 8GB)
254- tiger service create --name auto-memory --type postgres -- cpu 2000
261+ tiger service create --name auto-memory --cpu 2000
255262
256263 # Create service specifying only memory (CPU will be auto-configured to 4000m)
257- tiger service create --name auto-cpu --type timescaledb -- memory 16
264+ tiger service create --name auto-cpu --memory 16
258265
259266 # Create service without waiting for completion
260- tiger service create --name quick-db --type postgres --cpu 1000 --memory 4 --replicas 1 -- no-wait
267+ tiger service create --name quick-db --no-wait
261268
262269 # Create service with custom wait timeout
263- tiger service create --name patient-db --type timescaledb --cpu 2000 --memory 8 --replicas 2 --wait-timeout 1h
270+ tiger service create --name patient-db --wait-timeout 1h
271+
272+ Free Tier:
273+ When using --free, resource flags (--cpu, --memory, --replicas, --addons, --region) cannot be specified
264274
265- Allowed CPU/Memory Configurations:
275+ Allowed CPU/Memory Configurations (non-free services) :
266276 0.5 CPU (500m) / 2GB | 1 CPU (1000m) / 4GB | 2 CPU (2000m) / 8GB | 4 CPU (4000m) / 16GB
267277 8 CPU (8000m) / 32GB | 16 CPU (16000m) / 64GB | 32 CPU (32000m) / 128GB
268278
@@ -283,29 +293,50 @@ Note: You can specify both CPU and memory together, or specify only one (the oth
283293 if createServiceName == "" {
284294 createServiceName = util .GenerateServiceName ()
285295 }
286- if createServiceType == "" {
287- return fmt .Errorf ("service type is required (--type)" )
288- }
289- if createRegionCode == "" {
290- return fmt .Errorf ("region code cannot be empty (--region)" )
291- }
292- if createReplicaCount < 0 {
293- return fmt .Errorf ("replica count must be non-negative (--replicas)" )
294- }
295296
296- // Check which flags were explicitly set
297- cpuFlagSet := cmd .Flags ().Changed ("cpu" )
298- memoryFlagSet := cmd .Flags ().Changed ("memory" )
297+ // Validate free tier restrictions
298+ var addons []string
299+ if createFree {
300+ // Check which flags were explicitly set by the user
301+ if cmd .Flags ().Changed ("addons" ) {
302+ return fmt .Errorf ("--addons cannot be specified with --free" )
303+ }
304+ if cmd .Flags ().Changed ("region" ) {
305+ return fmt .Errorf ("--region cannot be specified with --free" )
306+ }
307+ if cmd .Flags ().Changed ("cpu" ) {
308+ return fmt .Errorf ("--cpu cannot be specified with --free" )
309+ }
310+ if cmd .Flags ().Changed ("memory" ) {
311+ return fmt .Errorf ("--memory cannot be specified with --free" )
312+ }
313+ if cmd .Flags ().Changed ("replicas" ) {
314+ return fmt .Errorf ("--replicas cannot be specified with --free" )
315+ }
316+ } else {
317+ // For non-free services, validate addons and resources
318+ addons , err = util .ValidateAddons (createAddons )
319+ if err != nil {
320+ return err
321+ }
322+ if createRegionCode == "" {
323+ return fmt .Errorf ("region code cannot be empty (--region)" )
324+ }
325+ if createReplicaCount < 0 {
326+ return fmt .Errorf ("replica count must be non-negative (--replicas)" )
327+ }
299328
300- // Validate and normalize CPU/Memory configuration
301- cpuMillis , memoryGbs , err := util .ValidateAndNormalizeCPUMemory (
302- createCpuMillis , createMemoryGbs , cpuFlagSet , memoryFlagSet ,
303- )
304- if err != nil {
305- return err
329+ cpuFlagSet := cmd .Flags ().Changed ("cpu" )
330+ memoryFlagSet := cmd .Flags ().Changed ("memory" )
331+
332+ // Validate and normalize CPU/Memory configuration
333+ createCpuMillis , createMemoryGbs , err = util .ValidateAndNormalizeCPUMemory (
334+ createCpuMillis , createMemoryGbs , cpuFlagSet , memoryFlagSet ,
335+ )
336+ if err != nil {
337+ return err
338+ }
306339 }
307- createCpuMillis = cpuMillis
308- createMemoryGbs = memoryGbs
309340
310341 // Validate wait timeout (Cobra handles parsing automatically)
311342 if createWaitTimeout <= 0 {
@@ -314,12 +345,6 @@ Note: You can specify both CPU and memory together, or specify only one (the oth
314345
315346 cmd .SilenceUsage = true
316347
317- // Validate service type
318- if ! util .IsValidServiceType (createServiceType ) {
319- return fmt .Errorf ("invalid service type '%s'. Valid types: %s" , createServiceType , strings .Join (util .ValidServiceTypes (), ", " ))
320- }
321- serviceTypeUpper := strings .ToUpper (createServiceType )
322-
323348 // Get API key for authentication
324349 apiKey , err := getAPIKeyForService ()
325350 if err != nil {
@@ -334,12 +359,19 @@ Note: You can specify both CPU and memory together, or specify only one (the oth
334359
335360 // Prepare service creation request
336361 serviceCreateReq := api.ServiceCreate {
337- Name : createServiceName ,
338- ServiceType : api .ServiceType (serviceTypeUpper ),
339- RegionCode : createRegionCode ,
340- ReplicaCount : createReplicaCount ,
341- CpuMillis : createCpuMillis ,
342- MemoryGbs : float32 (createMemoryGbs ),
362+ Name : createServiceName ,
363+ }
364+
365+ // Set free flag if specified
366+ if createFree {
367+ serviceCreateReq .Free = & createFree
368+ serviceCreateReq .RegionCode = "us-east-1"
369+ } else {
370+ serviceCreateReq .Addons = util .ConvertAddonsToAPI (addons )
371+ serviceCreateReq .RegionCode = createRegionCode
372+ serviceCreateReq .ReplicaCount = createReplicaCount
373+ serviceCreateReq .CpuMillis = createCpuMillis
374+ serviceCreateReq .MemoryGbs = createMemoryGbs
343375 }
344376
345377 // Make API call to create service
@@ -414,14 +446,15 @@ Note: You can specify both CPU and memory together, or specify only one (the oth
414446
415447 // Add flags
416448 cmd .Flags ().StringVar (& createServiceName , "name" , "" , "Service name (auto-generated if not provided)" )
417- cmd .Flags ().StringVar ( & createServiceType , "type " , util .ServiceTypeTimescaleDB , fmt .Sprintf ("Service type (%s)" , strings .Join (util .ValidServiceTypes (), ", " )))
449+ cmd .Flags ().StringSliceVar ( & createAddons , "addons " , [] string { util .AddonTimeSeries } , fmt .Sprintf ("Addons to enable (%s, or 'none' for PostgreSQL-only )" , strings .Join (util .ValidAddons (), ", " )))
418450 cmd .Flags ().StringVar (& createRegionCode , "region" , "us-east-1" , "Region code" )
419451 cmd .Flags ().IntVar (& createCpuMillis , "cpu" , 500 , "CPU allocation in millicores" )
420- cmd .Flags ().Float64Var (& createMemoryGbs , "memory" , 2.0 , "Memory allocation in gigabytes" )
452+ cmd .Flags ().IntVar (& createMemoryGbs , "memory" , 2 , "Memory allocation in gigabytes" )
421453 cmd .Flags ().IntVar (& createReplicaCount , "replicas" , 0 , "Number of high-availability replicas" )
422454 cmd .Flags ().BoolVar (& createNoWait , "no-wait" , false , "Don't wait for operation to complete" )
423455 cmd .Flags ().DurationVar (& createWaitTimeout , "wait-timeout" , 30 * time .Minute , "Wait timeout duration (e.g., 30m, 1h30m, 90s)" )
424456 cmd .Flags ().BoolVar (& createNoSetDefault , "no-set-default" , false , "Don't set this service as the default service" )
457+ cmd .Flags ().BoolVar (& createFree , "free" , false , "Create a free tier service (limitations apply)" )
425458
426459 return cmd
427460}
@@ -607,10 +640,16 @@ func outputServiceTable(cmd *cobra.Command, service api.Service) error {
607640 } else {
608641 table .Append ("CPU" , fmt .Sprintf ("%.1f cores (%dm)" , cpuCores , * resource .Spec .CpuMillis ))
609642 }
643+ } else {
644+ // CPU is null - this indicates a free tier service
645+ table .Append ("CPU" , "shared" )
610646 }
611647
612648 if resource .Spec .MemoryGbs != nil {
613649 table .Append ("Memory" , fmt .Sprintf ("%d GB" , * resource .Spec .MemoryGbs ))
650+ } else {
651+ // Memory is null - this indicates a free tier service
652+ table .Append ("Memory" , "shared" )
614653 }
615654 }
616655 }
0 commit comments