Skip to content

Commit

Permalink
Add appstudio redhat nstemplatetier
Browse files Browse the repository at this point in the history
Signed-off-by: Jing Qi <[email protected]>
  • Loading branch information
jinqi7 committed Jun 28, 2023
1 parent d25f9cb commit 437abd7
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 2 deletions.
2 changes: 1 addition & 1 deletion test/e2e/nstemplatetier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestNSTemplateTiers(t *testing.T) {
Resources()

// all tiers to check - keep the base as the last one, it will verify downgrade back to the default tier at the end of the test
tiersToCheck := []string{"advanced", "baseextendedidling", "baselarge", "test", "appstudio", "appstudio-env", "base1ns", "base1nsnoidling", "base1ns6didler", "base"}
tiersToCheck := []string{"advanced", "baseextendedidling", "baselarge", "test", "appstudio", "appstudio-redhat", "appstudio-env", "base1ns", "base1nsnoidling", "base1ns6didler", "base"}

// when the tiers are created during the startup then we can verify them
allTiers := &toolchainv1alpha1.NSTemplateTierList{}
Expand Down
157 changes: 156 additions & 1 deletion testsupport/tiers/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
"github.com/codeready-toolchain/toolchain-e2e/testsupport/wait"

"github.com/davecgh/go-spew/spew"
Expand All @@ -27,6 +28,7 @@ const (
// tier names
advanced = "advanced"
appstudio = "appstudio"
appstudioRedhat = "appstudio-redhat"
appstudioEnv = "appstudio-env"
base = "base"
base1ns = "base1ns"
Expand Down Expand Up @@ -78,6 +80,9 @@ func NewChecksForTier(tier *toolchainv1alpha1.NSTemplateTier) (TierChecks, error
case appstudio:
return &appstudioTierChecks{tierName: appstudio}, nil

case appstudioRedhat:
return &appstudioRedhatTierChecks{tierName: appstudio}, nil

case appstudioEnv:
return &appstudioEnvTierChecks{tierName: appstudioEnv}, nil

Expand Down Expand Up @@ -382,6 +387,12 @@ func commonNetworkPolicyChecks() []namespaceObjectsCheck {
}
}

func externalSecretChecks() []namespaceObjectsCheck {
return []namespaceObjectsCheck{
externalSecretSnykSharedToken(),
}
}

type advancedTierChecks struct {
baseTierChecks
}
Expand Down Expand Up @@ -458,7 +469,7 @@ func (a *appstudioTierChecks) GetNamespaceObjectChecks(_ string) []namespaceObje
pipelineRunnerRoleBinding(),
}

checks = append(checks, append(commonNetworkPolicyChecks(), networkPolicyAllowFromCRW(), numberOfNetworkPolicies(6))...)
checks = append(checks, append(commonNetworkPolicyChecks(), externalSecretChecks(), networkPolicyAllowFromCRW(), numberOfNetworkPolicies(6))...)
return checks
}

Expand Down Expand Up @@ -531,6 +542,107 @@ func (a *appstudioTierChecks) GetClusterObjectChecks() []clusterObjectsCheck {
pipelineRunnerClusterRole())
}

type appstudioRedhatTierChecks struct {
tierName string
}

func (a *appstudioRedhatTierChecks) GetNamespaceObjectChecks(_ string) []namespaceObjectsCheck {
checks := []namespaceObjectsCheck{
resourceQuotaComputeDeploy("20", "32Gi", "1750m", "32Gi"),
resourceQuotaComputeBuild("60", "64Gi", "6", "32Gi"),
resourceQuotaStorage("50Gi", "50Gi", "50Gi", "12"),
limitRange("2", "2Gi", "10m", "256Mi"),
numberOfLimitRanges(1),
toolchainSaReadRole(),
memberOperatorSaReadRoleBinding(),
gitOpsServiceLabel(),
appstudioWorkSpaceNameLabel(),
redhatInternalTenantLabel(),
environment("development"),
resourceQuotaAppstudioCrds("512", "512", "512"),
resourceQuotaAppstudioCrdsBuild("512"),
resourceQuotaAppstudioCrdsGitops("512", "512", "512", "512", "512"),
resourceQuotaAppstudioCrdsIntegration("512", "512", "512"),
resourceQuotaAppstudioCrdsRelease("512", "512", "512", "512", "512"),
resourceQuotaAppstudioCrdsEnterpriseContract("512"),
resourceQuotaAppstudioCrdsSPI("512", "512", "512", "512", "512"),
pipelineServiceAccount(),
pipelineRunnerRoleBinding(),
}

checks = append(checks, append(commonNetworkPolicyChecks(), networkPolicyAllowFromCRW(), numberOfNetworkPolicies(6))...)
return checks
}

func (a *appstudioRedhatTierChecks) GetSpaceRoleChecks(spaceRoles map[string][]string) ([]spaceRoleObjectsCheck, error) {
checks := []spaceRoleObjectsCheck{}
roles := 0
rolebindings := 0
for role, usernames := range spaceRoles {
switch role {
case "admin":
checks = append(checks, appstudioUserActionsRole())
roles++
for _, userName := range usernames {
checks = append(checks,
appstudioUserActionsRoleBinding(userName, "admin"),
appstudioViewRoleBinding(userName),
)
rolebindings += 2
}
case "maintainer":
checks = append(checks, appstudioMaintainerUserActionsRole())
roles++
for _, userName := range usernames {
checks = append(checks,
appstudioUserActionsRoleBinding(userName, "maintainer"),
appstudioViewRoleBinding(userName),
)
rolebindings += 2
}
case "contributor":
checks = append(checks, appstudioContributorUserActionsRole())
roles++
for _, userName := range usernames {
checks = append(checks,
appstudioUserActionsRoleBinding(userName, "contributor"),
appstudioViewRoleBinding(userName),
)
rolebindings += 2
}
default:
return nil, fmt.Errorf("unexpected template name: '%s'", role)
}
}
// also count the roles, rolebindings and service accounts
checks = append(checks,
numberOfToolchainRoles(roles+1), // +1 for `toolchain-sa-read`
numberOfToolchainRoleBindings(rolebindings+2), // +2 for `member-operator-sa-read` and `appstudio-pipelines-runner-rolebinding`
)
return checks, nil
}

func (a *appstudioRedhatTierChecks) GetExpectedTemplateRefs(t *testing.T, hostAwait *wait.HostAwaitility) TemplateRefs {
templateRefs := GetTemplateRefs(t, hostAwait, a.tierName)
verifyNsTypes(t, a.tierName, templateRefs, "tenant")
return templateRefs
}

func (a *appstudioRedhatTierChecks) GetClusterObjectChecks() []clusterObjectsCheck {
return clusterObjectsChecks(
clusterResourceQuotaDeployments("150"),
clusterResourceQuotaReplicas(),
clusterResourceQuotaRoutes(),
clusterResourceQuotaJobs(),
clusterResourceQuotaServices(),
clusterResourceQuotaBuildConfig(),
clusterResourceQuotaSecrets(),
clusterResourceQuotaConfigMap(),
numberOfClusterResourceQuotas(8),
idlers(0, ""),
pipelineRunnerClusterRole())
}

type appstudioEnvTierChecks struct {
tierName string
}
Expand Down Expand Up @@ -955,6 +1067,38 @@ func limitRange(cpuLimit, memoryLimit, cpuRequest, memoryRequest string) namespa
}
}

func externalSecretSnykSharedToken() namespaceObjectsCheck {
return func(t *testing.T, ns *corev1.Namespace, memberAwait *wait.MemberAwaitility, userName string) {
es, err := memberAwait.WaitForExternalSecret(t, ns, "snyk-shared-token")
require.NoError(t, err)
assert.Equal(t, toolchainv1alpha1.ProviderLabelValue, es.ObjectMeta.Labels[toolchainv1alpha1.ProviderLabelKey])
expected := &esv1beta1.ExternalSecret{
Annotations: map[string]string{
"argocd.argoproj.io/sync-options": "SkipDryRunOnMissingResource=true",
"argocd.argoproj.io/sync-wave": "-1",
},
},
Spec: esv1beta1.ExternalSecretSpec{
DataFrom: []esv1beta1.ExternalSecretDataFromRemoteRef{
{
Extract: &esv1beta1.ExternalSecretDataRemoteRef{
Key: "snyk-shared-secret",
},
},
},
SecretStoreRef: esv1beta1.SecretStoreRef{
Name: "appsre-redhat-tenant-vault",
},
Target: esv1beta1.ExternalSecretTarget{
Name: "snyk-secret",
},
},
}

assert.Equal(t, expected.Spec, es.Spec)
}
}

func networkPolicySameNamespace() namespaceObjectsCheck {
return func(t *testing.T, ns *corev1.Namespace, memberAwait *wait.MemberAwaitility, userName string) {
np, err := memberAwait.WaitForNetworkPolicy(t, ns, "allow-same-namespace")
Expand Down Expand Up @@ -1452,6 +1596,17 @@ func appstudioWorkSpaceNameLabel() namespaceObjectsCheck {
}
}

func redhatInternalTenantLabel() namespaceObjectsCheck {
return func(t *testing.T, ns *corev1.Namespace, memberAwait *wait.MemberAwaitility, owner string) {

labelWaitCriterion := []wait.LabelWaitCriterion{}
labelWaitCriterion = append(labelWaitCriterion, wait.UntilObjectHasLabel("redhat-internal-tenent/label", "true"))

_, err := memberAwait.WaitForNamespaceWithName(t, ns.Name, labelWaitCriterion...)
require.NoError(t, err)
}
}

func environment(name string) namespaceObjectsCheck {
return func(t *testing.T, ns *corev1.Namespace, memberAwait *wait.MemberAwaitility, owner string) {
_, err := memberAwait.WaitForEnvironment(t, ns.Name, name, toolchainLabelsWaitCriterion(owner)...)
Expand Down
26 changes: 26 additions & 0 deletions testsupport/wait/member.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/codeready-toolchain/toolchain-common/pkg/cluster"
"github.com/codeready-toolchain/toolchain-common/pkg/test"
appstudiov1 "github.com/codeready-toolchain/toolchain-e2e/testsupport/appstudio/api/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
"github.com/davecgh/go-spew/spew"
"github.com/ghodss/yaml"
quotav1 "github.com/openshift/api/quota/v1"
Expand Down Expand Up @@ -936,6 +937,31 @@ func (a *MemberAwaitility) WaitForNetworkPolicy(t *testing.T, namespace *corev1.
return np, err
}

// WaitForExternalSecret waits until a ExternalSecret with the given name exists in the given namespace
func (a *MemberAwaitility) WaitForExternalSecret(t *testing.T, namespace *corev1.Namespace, name string) (*esv1beta1.ExternalSecret, error) {
t.Logf("waiting for ExternalSecret '%s' in namespace '%s'", name, namespace.Name)
es := &esv1beta1.ExternalSecret{}
err := wait.Poll(a.RetryInterval, a.Timeout, func() (done bool, err error) {
obj := &esv1beta1.ExternalSecret{}
if err := a.Client.Get(context.TODO(), types.NamespacedName{Namespace: namespace.Name, Name: name}, obj); err != nil {
if errors.IsNotFound(err) {
allESs := &esv1beta1.ExternalSecretList{}
if err := a.Client.List(context.TODO(), allESs, client.InNamespace(namespace)); err != nil {
return false, err
}
return false, nil
}
return false, err
}
es = obj
return true, nil
})
if err != nil {
t.Logf("failed to wait for ExternalSecret '%s' in namespace '%s'", name, namespace.Name)
}
return es, err
}

// WaitForRole waits until a Role with the given name exists in the given namespace
func (a *MemberAwaitility) WaitForRole(t *testing.T, namespace *corev1.Namespace, name string, criteria ...LabelWaitCriterion) (*rbacv1.Role, error) {
t.Logf("waiting for Role '%s' in namespace '%s'", name, namespace.Name)
Expand Down

0 comments on commit 437abd7

Please sign in to comment.