@@ -519,6 +519,207 @@ func TestTemplateEdit(t *testing.T) {
519
519
assert .Equal (t , template .RestartRequirement .Weeks , updated .RestartRequirement .Weeks )
520
520
})
521
521
})
522
+ // TODO(@dean): remove this test when we remove max_ttl
523
+ t .Run ("MaxTTL" , func (t * testing.T ) {
524
+ t .Parallel ()
525
+ t .Run ("BlockedAGPL" , func (t * testing.T ) {
526
+ t .Parallel ()
527
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
528
+ user := coderdtest .CreateFirstUser (t , client )
529
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
530
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
531
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
532
+ ctr .DefaultTTLMillis = nil
533
+ ctr .MaxTTLMillis = nil
534
+ })
535
+
536
+ // Test the cli command.
537
+ cmdArgs := []string {
538
+ "templates" ,
539
+ "edit" ,
540
+ template .Name ,
541
+ "--max-ttl" , "1h" ,
542
+ }
543
+ inv , root := clitest .New (t , cmdArgs ... )
544
+ clitest .SetupConfig (t , client , root )
545
+
546
+ ctx := testutil .Context (t , testutil .WaitLong )
547
+ err := inv .WithContext (ctx ).Run ()
548
+ require .Error (t , err )
549
+ require .ErrorContains (t , err , "appears to be an AGPL deployment" )
550
+
551
+ // Assert that the template metadata did not change.
552
+ updated , err := client .Template (context .Background (), template .ID )
553
+ require .NoError (t , err )
554
+ assert .Equal (t , template .Name , updated .Name )
555
+ assert .Equal (t , template .Description , updated .Description )
556
+ assert .Equal (t , template .Icon , updated .Icon )
557
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
558
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
559
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
560
+ })
561
+
562
+ t .Run ("BlockedNotEntitled" , func (t * testing.T ) {
563
+ t .Parallel ()
564
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
565
+ user := coderdtest .CreateFirstUser (t , client )
566
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
567
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
568
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
569
+ ctr .DefaultTTLMillis = nil
570
+ ctr .MaxTTLMillis = nil
571
+ })
572
+
573
+ // Make a proxy server that will return a valid entitlements
574
+ // response, but without advanced scheduling entitlement.
575
+ proxy := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
576
+ if r .URL .Path == "/api/v2/entitlements" {
577
+ res := codersdk.Entitlements {
578
+ Features : map [codersdk.FeatureName ]codersdk.Feature {},
579
+ Warnings : []string {},
580
+ Errors : []string {},
581
+ HasLicense : true ,
582
+ Trial : true ,
583
+ RequireTelemetry : false ,
584
+ }
585
+ for _ , feature := range codersdk .FeatureNames {
586
+ res .Features [feature ] = codersdk.Feature {
587
+ Entitlement : codersdk .EntitlementNotEntitled ,
588
+ Enabled : false ,
589
+ Limit : nil ,
590
+ Actual : nil ,
591
+ }
592
+ }
593
+ httpapi .Write (r .Context (), w , http .StatusOK , res )
594
+ return
595
+ }
596
+
597
+ // Otherwise, proxy the request to the real API server.
598
+ httputil .NewSingleHostReverseProxy (client .URL ).ServeHTTP (w , r )
599
+ }))
600
+ defer proxy .Close ()
601
+
602
+ // Create a new client that uses the proxy server.
603
+ proxyURL , err := url .Parse (proxy .URL )
604
+ require .NoError (t , err )
605
+ proxyClient := codersdk .New (proxyURL )
606
+ proxyClient .SetSessionToken (client .SessionToken ())
607
+
608
+ // Test the cli command.
609
+ cmdArgs := []string {
610
+ "templates" ,
611
+ "edit" ,
612
+ template .Name ,
613
+ "--max-ttl" , "1h" ,
614
+ }
615
+ inv , root := clitest .New (t , cmdArgs ... )
616
+ clitest .SetupConfig (t , proxyClient , root )
617
+
618
+ ctx := testutil .Context (t , testutil .WaitLong )
619
+ err = inv .WithContext (ctx ).Run ()
620
+ require .Error (t , err )
621
+ require .ErrorContains (t , err , "license is not entitled" )
622
+
623
+ // Assert that the template metadata did not change.
624
+ updated , err := client .Template (context .Background (), template .ID )
625
+ require .NoError (t , err )
626
+ assert .Equal (t , template .Name , updated .Name )
627
+ assert .Equal (t , template .Description , updated .Description )
628
+ assert .Equal (t , template .Icon , updated .Icon )
629
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
630
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
631
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
632
+ })
633
+ t .Run ("Entitled" , func (t * testing.T ) {
634
+ t .Parallel ()
635
+ client := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
636
+ user := coderdtest .CreateFirstUser (t , client )
637
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
638
+ _ = coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
639
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID , func (ctr * codersdk.CreateTemplateRequest ) {
640
+ ctr .DefaultTTLMillis = nil
641
+ ctr .MaxTTLMillis = nil
642
+ })
643
+
644
+ // Make a proxy server that will return a valid entitlements
645
+ // response, including a valid advanced scheduling entitlement.
646
+ var updateTemplateCalled int64
647
+ proxy := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
648
+ if r .URL .Path == "/api/v2/entitlements" {
649
+ res := codersdk.Entitlements {
650
+ Features : map [codersdk.FeatureName ]codersdk.Feature {},
651
+ Warnings : []string {},
652
+ Errors : []string {},
653
+ HasLicense : true ,
654
+ Trial : true ,
655
+ RequireTelemetry : false ,
656
+ }
657
+ for _ , feature := range codersdk .FeatureNames {
658
+ var one int64 = 1
659
+ res .Features [feature ] = codersdk.Feature {
660
+ Entitlement : codersdk .EntitlementNotEntitled ,
661
+ Enabled : true ,
662
+ Limit : & one ,
663
+ Actual : & one ,
664
+ }
665
+ }
666
+ httpapi .Write (r .Context (), w , http .StatusOK , res )
667
+ return
668
+ }
669
+ if strings .HasPrefix (r .URL .Path , "/api/v2/templates/" ) {
670
+ body , err := io .ReadAll (r .Body )
671
+ require .NoError (t , err )
672
+ _ = r .Body .Close ()
673
+
674
+ var req codersdk.UpdateTemplateMeta
675
+ err = json .Unmarshal (body , & req )
676
+ require .NoError (t , err )
677
+ assert .Equal (t , time .Hour .Milliseconds (), req .MaxTTLMillis )
678
+
679
+ r .Body = io .NopCloser (bytes .NewReader (body ))
680
+ atomic .AddInt64 (& updateTemplateCalled , 1 )
681
+ // We still want to call the real route.
682
+ }
683
+
684
+ // Otherwise, proxy the request to the real API server.
685
+ httputil .NewSingleHostReverseProxy (client .URL ).ServeHTTP (w , r )
686
+ }))
687
+ defer proxy .Close ()
688
+
689
+ // Create a new client that uses the proxy server.
690
+ proxyURL , err := url .Parse (proxy .URL )
691
+ require .NoError (t , err )
692
+ proxyClient := codersdk .New (proxyURL )
693
+ proxyClient .SetSessionToken (client .SessionToken ())
694
+
695
+ // Test the cli command.
696
+ cmdArgs := []string {
697
+ "templates" ,
698
+ "edit" ,
699
+ template .Name ,
700
+ "--max-ttl" , "1h" ,
701
+ }
702
+ inv , root := clitest .New (t , cmdArgs ... )
703
+ clitest .SetupConfig (t , proxyClient , root )
704
+
705
+ ctx := testutil .Context (t , testutil .WaitLong )
706
+ err = inv .WithContext (ctx ).Run ()
707
+ require .NoError (t , err )
708
+
709
+ require .EqualValues (t , 1 , atomic .LoadInt64 (& updateTemplateCalled ))
710
+
711
+ // Assert that the template metadata did not change. We verify the
712
+ // correct request gets sent to the server already.
713
+ updated , err := client .Template (context .Background (), template .ID )
714
+ require .NoError (t , err )
715
+ assert .Equal (t , template .Name , updated .Name )
716
+ assert .Equal (t , template .Description , updated .Description )
717
+ assert .Equal (t , template .Icon , updated .Icon )
718
+ assert .Equal (t , template .DisplayName , updated .DisplayName )
719
+ assert .Equal (t , template .DefaultTTLMillis , updated .DefaultTTLMillis )
720
+ assert .Equal (t , template .MaxTTLMillis , updated .MaxTTLMillis )
721
+ })
722
+ })
522
723
t .Run ("AllowUserScheduling" , func (t * testing.T ) {
523
724
t .Parallel ()
524
725
t .Run ("BlockedAGPL" , func (t * testing.T ) {
0 commit comments