@@ -32,6 +32,7 @@ const (
3232 base1ns = "base1ns"
3333 base1ns6didler = "base1ns6didler"
3434 base1nsnoidling = "base1nsnoidling"
35+ claw = "claw"
3536
3637 // common CPU limits
3738 baseCPULimit = "40000m"
@@ -62,6 +63,8 @@ func NewChecksForTier(tier *toolchainv1alpha1.NSTemplateTier) (TierChecks, error
6263 return & appstudiolargeTierChecks {appstudioTierChecks {tierName : appstudiolarge }}, nil
6364 case appstudioEnv :
6465 return & appstudioEnvTierChecks {tierName : appstudioEnv }, nil
66+ case claw :
67+ return & clawTierChecks {tierName : claw }, nil
6568 default :
6669 return nil , fmt .Errorf ("no assertion implementation found for %s" , tier .Name )
6770 }
@@ -525,6 +528,170 @@ func (a *appstudioEnvTierChecks) GetClusterObjectChecks() []clusterObjectsCheck
525528 idlers (0 , "env" ))
526529}
527530
531+ type clawTierChecks struct {
532+ tierName string
533+ }
534+
535+ func (a * clawTierChecks ) GetNamespaceObjectChecks (_ string ) []namespaceObjectsCheck {
536+ checks := []namespaceObjectsCheck {
537+ resourceQuotaComputeDeployNoScope ("8" , "10Gi" , "1" , "3Gi" ),
538+ resourceQuotaStorage ("5Gi" , "15Gi" , "5Gi" , "1" ),
539+ limitRange ("500m" , "512Mi" , "10m" , "64Mi" ),
540+ numberOfLimitRanges (1 ),
541+ execPodsRole (),
542+ crtadminPodsRoleBinding (),
543+ crtadminViewRoleBinding (),
544+ networkPolicySameNamespace (),
545+ networkPolicyAllowFromIngress (),
546+ networkPolicyAllowFromMonitoring (),
547+ networkPolicyAllowFromOlmNamespaces (),
548+ networkPolicyAllowFromConsoleNamespaces (),
549+ numberOfNetworkPolicies (5 ),
550+ }
551+ return checks
552+ }
553+
554+ func (a * clawTierChecks ) GetSpaceRoleChecks (spaceRoles map [string ][]string ) ([]spaceRoleObjectsCheck , error ) {
555+ checks := []spaceRoleObjectsCheck {}
556+ roles := 0
557+ rolebindings := 0
558+ for role , usernames := range spaceRoles {
559+ switch role {
560+ case "admin" :
561+ checks = append (checks , clawUserRole ())
562+ roles ++
563+ for _ , userName := range usernames {
564+ checks = append (checks , clawUserRoleBinding (userName ))
565+ rolebindings ++
566+ }
567+ default :
568+ return nil , fmt .Errorf ("unexpected template name: '%s'" , role )
569+ }
570+ }
571+ checks = append (checks ,
572+ numberOfToolchainRoles (roles + 1 ), // +1 for `exec-pods`
573+ numberOfToolchainRoleBindings (rolebindings + 2 ), // +2 for `crtadmin-pods` and `crtadmin-view`
574+ )
575+ return checks , nil
576+ }
577+
578+ func (a * clawTierChecks ) GetExpectedTemplateRefs (t * testing.T , hostAwait * wait.HostAwaitility ) TemplateRefs {
579+ templateRefs := GetTemplateRefs (t , hostAwait , a .tierName )
580+ verifyNsTypes (t , a .tierName , templateRefs , "claw" )
581+ return templateRefs
582+ }
583+
584+ func (a * clawTierChecks ) GetClusterObjectChecks () []clusterObjectsCheck {
585+ return clusterObjectsChecks (
586+ clusterResourceQuotaClaw (),
587+ numberOfClusterResourceQuotas (1 ),
588+ idlers (43200 , "claw" ))
589+ }
590+
591+ func clusterResourceQuotaClaw () clusterObjectsCheckCreator {
592+ return func () clusterObjectsCheck {
593+ return func (t * testing.T , memberAwait * wait.MemberAwaitility , userName , tierLabel string ) {
594+ var err error
595+ hard := make (map [corev1.ResourceName ]resource.Quantity )
596+ hard [count ("deployments.apps" )], err = resource .ParseQuantity ("5" )
597+ require .NoError (t , err )
598+ hard [count (corev1 .ResourcePods )], err = resource .ParseQuantity ("10" )
599+ require .NoError (t , err )
600+ hard [count ("routes.route.openshift.io" )], err = resource .ParseQuantity ("3" )
601+ require .NoError (t , err )
602+ hard [count (corev1 .ResourceServices )], err = resource .ParseQuantity ("5" )
603+ require .NoError (t , err )
604+ hard [count (corev1 .ResourceSecrets )], err = resource .ParseQuantity ("50" )
605+ require .NoError (t , err )
606+ hard [count (corev1 .ResourceConfigMaps )], err = resource .ParseQuantity ("10" )
607+ require .NoError (t , err )
608+
609+ _ , err = memberAwait .WaitForClusterResourceQuota (t , fmt .Sprintf ("for-%s-claw" , userName ),
610+ crqToolchainLabelsWaitCriterion (userName ),
611+ clusterResourceQuotaMatches (userName , tierLabel , hard ),
612+ )
613+ require .NoError (t , err )
614+ }
615+ }
616+ }
617+
618+ func resourceQuotaComputeDeployNoScope (cpuLimit , memoryLimit , cpuRequest , memoryRequest string ) namespaceObjectsCheck {
619+ return func (t * testing.T , ns * corev1.Namespace , memberAwait * wait.MemberAwaitility , _ string ) {
620+ var err error
621+ spec := corev1.ResourceQuotaSpec {
622+ Hard : make (map [corev1.ResourceName ]resource.Quantity ),
623+ }
624+ spec .Hard [corev1 .ResourceLimitsCPU ], err = resource .ParseQuantity (cpuLimit )
625+ require .NoError (t , err )
626+ spec .Hard [corev1 .ResourceLimitsMemory ], err = resource .ParseQuantity (memoryLimit )
627+ require .NoError (t , err )
628+ spec .Hard [corev1 .ResourceRequestsCPU ], err = resource .ParseQuantity (cpuRequest )
629+ require .NoError (t , err )
630+ spec .Hard [corev1 .ResourceRequestsMemory ], err = resource .ParseQuantity (memoryRequest )
631+ require .NoError (t , err )
632+
633+ criteria := resourceQuotaMatches (ns .Name , "compute-deploy" , spec )
634+ _ , err = memberAwait .WaitForResourceQuota (t , ns .Name , "compute-deploy" , criteria )
635+ require .NoError (t , err )
636+ }
637+ }
638+
639+ func clawUserRole () spaceRoleObjectsCheck {
640+ return func (t * testing.T , ns * corev1.Namespace , memberAwait * wait.MemberAwaitility , owner string ) {
641+ role , err := memberAwait .WaitForRole (t , ns , "claw-user" , toolchainLabelsWaitCriterion (owner )... )
642+ require .NoError (t , err )
643+ expected := & rbacv1.Role {
644+ Rules : []rbacv1.PolicyRule {
645+ {
646+ APIGroups : []string {"claw.sandbox.redhat.com" },
647+ Resources : []string {"claws" },
648+ Verbs : []string {"get" , "list" , "watch" , "create" , "update" , "patch" , "delete" },
649+ },
650+ {
651+ APIGroups : []string {"" },
652+ Resources : []string {"pods" },
653+ Verbs : []string {"get" , "list" , "watch" },
654+ },
655+ {
656+ APIGroups : []string {"" },
657+ Resources : []string {"pods/log" },
658+ Verbs : []string {"get" , "list" },
659+ },
660+ {
661+ APIGroups : []string {"" },
662+ Resources : []string {"events" },
663+ Verbs : []string {"get" , "list" , "watch" },
664+ },
665+ {
666+ APIGroups : []string {"route.openshift.io" },
667+ Resources : []string {"routes" },
668+ Verbs : []string {"get" , "list" , "watch" },
669+ },
670+ {
671+ APIGroups : []string {"" },
672+ Resources : []string {"secrets" },
673+ Verbs : []string {"create" , "update" , "patch" , "delete" },
674+ },
675+ },
676+ }
677+ assert .Len (t , role .Rules , len (expected .Rules ))
678+ assert .Equal (t , expected .Rules , role .Rules )
679+ }
680+ }
681+
682+ func clawUserRoleBinding (userName string ) spaceRoleObjectsCheck {
683+ return func (t * testing.T , ns * corev1.Namespace , memberAwait * wait.MemberAwaitility , owner string ) {
684+ rb , err := memberAwait .WaitForRoleBinding (t , ns , userName + "-claw-user" , toolchainLabelsWaitCriterion (owner )... )
685+ require .NoError (t , err )
686+ assert .Len (t , rb .Subjects , 1 )
687+ assert .Equal (t , "User" , rb .Subjects [0 ].Kind )
688+ assert .Equal (t , userName , rb .Subjects [0 ].Name )
689+ assert .Equal (t , "claw-user" , rb .RoleRef .Name )
690+ assert .Equal (t , "Role" , rb .RoleRef .Kind )
691+ assert .Equal (t , "rbac.authorization.k8s.io" , rb .RoleRef .APIGroup )
692+ }
693+ }
694+
528695// verifyNsTypes checks that there's a namespace.TemplateRef that begins with `<tier>-<type>` for each given templateRef (and no more, no less)
529696func verifyNsTypes (t * testing.T , tier string , templateRefs TemplateRefs , expectedNSTypes ... string ) {
530697 require .Len (t , templateRefs .Namespaces , len (expectedNSTypes ))
0 commit comments