@@ -711,6 +711,156 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
711
711
return workspaces , nil
712
712
}
713
713
714
+ func (q * fakeQuerier ) GetWorkspaceCount (ctx context.Context , arg database.GetWorkspaceCountParams ) (int64 , error ) {
715
+ count , err := q .GetAuthorizedWorkspaceCount (ctx , arg , nil )
716
+ return count , err
717
+ }
718
+
719
+ //nolint:gocyclo
720
+ func (q * fakeQuerier ) GetAuthorizedWorkspaceCount (ctx context.Context , arg database.GetWorkspacesParams , authorizedFilter rbac.AuthorizeFilter ) (int64 , error ) {
721
+ q .mutex .RLock ()
722
+ defer q .mutex .RUnlock ()
723
+
724
+ workspaces := make ([]database.Workspace , 0 )
725
+ for _ , workspace := range q .workspaces {
726
+ if arg .OwnerID != uuid .Nil && workspace .OwnerID != arg .OwnerID {
727
+ continue
728
+ }
729
+
730
+ if arg .OwnerUsername != "" {
731
+ owner , err := q .GetUserByID (ctx , workspace .OwnerID )
732
+ if err == nil && ! strings .EqualFold (arg .OwnerUsername , owner .Username ) {
733
+ continue
734
+ }
735
+ }
736
+
737
+ if arg .TemplateName != "" {
738
+ template , err := q .GetTemplateByID (ctx , workspace .TemplateID )
739
+ if err == nil && ! strings .EqualFold (arg .TemplateName , template .Name ) {
740
+ continue
741
+ }
742
+ }
743
+
744
+ if ! arg .Deleted && workspace .Deleted {
745
+ continue
746
+ }
747
+
748
+ if arg .Name != "" && ! strings .Contains (strings .ToLower (workspace .Name ), strings .ToLower (arg .Name )) {
749
+ continue
750
+ }
751
+
752
+ if arg .Status != "" {
753
+ build , err := q .GetLatestWorkspaceBuildByWorkspaceID (ctx , workspace .ID )
754
+ if err != nil {
755
+ return 0 , xerrors .Errorf ("get latest build: %w" , err )
756
+ }
757
+
758
+ job , err := q .GetProvisionerJobByID (ctx , build .JobID )
759
+ if err != nil {
760
+ return 0 , xerrors .Errorf ("get provisioner job: %w" , err )
761
+ }
762
+
763
+ switch arg .Status {
764
+ case "pending" :
765
+ if ! job .StartedAt .Valid {
766
+ continue
767
+ }
768
+
769
+ case "starting" :
770
+ if ! job .StartedAt .Valid &&
771
+ ! job .CanceledAt .Valid &&
772
+ job .CompletedAt .Valid &&
773
+ time .Since (job .UpdatedAt ) > 30 * time .Second ||
774
+ build .Transition != database .WorkspaceTransitionStart {
775
+ continue
776
+ }
777
+
778
+ case "running" :
779
+ if ! job .CompletedAt .Valid &&
780
+ job .CanceledAt .Valid &&
781
+ job .Error .Valid ||
782
+ build .Transition != database .WorkspaceTransitionStart {
783
+ continue
784
+ }
785
+
786
+ case "stopping" :
787
+ if ! job .StartedAt .Valid &&
788
+ ! job .CanceledAt .Valid &&
789
+ job .CompletedAt .Valid &&
790
+ time .Since (job .UpdatedAt ) > 30 * time .Second ||
791
+ build .Transition != database .WorkspaceTransitionStop {
792
+ continue
793
+ }
794
+
795
+ case "stopped" :
796
+ if ! job .CompletedAt .Valid &&
797
+ job .CanceledAt .Valid &&
798
+ job .Error .Valid ||
799
+ build .Transition != database .WorkspaceTransitionStop {
800
+ continue
801
+ }
802
+
803
+ case "failed" :
804
+ if (! job .CanceledAt .Valid && ! job .Error .Valid ) ||
805
+ (! job .CompletedAt .Valid && ! job .Error .Valid ) {
806
+ continue
807
+ }
808
+
809
+ case "canceling" :
810
+ if ! job .CanceledAt .Valid && job .CompletedAt .Valid {
811
+ continue
812
+ }
813
+
814
+ case "canceled" :
815
+ if ! job .CanceledAt .Valid && ! job .CompletedAt .Valid {
816
+ continue
817
+ }
818
+
819
+ case "deleted" :
820
+ if ! job .StartedAt .Valid &&
821
+ job .CanceledAt .Valid &&
822
+ ! job .CompletedAt .Valid &&
823
+ time .Since (job .UpdatedAt ) > 30 * time .Second ||
824
+ build .Transition != database .WorkspaceTransitionDelete {
825
+ continue
826
+ }
827
+
828
+ case "deleting" :
829
+ if ! job .CompletedAt .Valid &&
830
+ job .CanceledAt .Valid &&
831
+ job .Error .Valid &&
832
+ build .Transition != database .WorkspaceTransitionDelete {
833
+ continue
834
+ }
835
+
836
+ default :
837
+ return 0 , xerrors .Errorf ("unknown workspace status in filter: %q" , arg .Status )
838
+ }
839
+ }
840
+
841
+ if len (arg .TemplateIds ) > 0 {
842
+ match := false
843
+ for _ , id := range arg .TemplateIds {
844
+ if workspace .TemplateID == id {
845
+ match = true
846
+ break
847
+ }
848
+ }
849
+ if ! match {
850
+ continue
851
+ }
852
+ }
853
+
854
+ // If the filter exists, ensure the object is authorized.
855
+ if authorizedFilter != nil && ! authorizedFilter .Eval (workspace .RBACObject ()) {
856
+ continue
857
+ }
858
+ workspaces = append (workspaces , workspace )
859
+ }
860
+
861
+ return int64 (len (workspaces )), nil
862
+ }
863
+
714
864
func (q * fakeQuerier ) GetWorkspaceByID (_ context.Context , id uuid.UUID ) (database.Workspace , error ) {
715
865
q .mutex .RLock ()
716
866
defer q .mutex .RUnlock ()
0 commit comments