Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic P0 Test Cases for Project #45381

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
188 changes: 148 additions & 40 deletions tests/v2/validation/projects/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,35 @@ import (
"github.com/rancher/shepherd/clients/rancher"
management "github.com/rancher/shepherd/clients/rancher/generated/management/v3"
"github.com/rancher/shepherd/extensions/defaults"
projectsApi "github.com/rancher/shepherd/extensions/kubeapi/projects"
rbacApi "github.com/rancher/shepherd/extensions/kubeapi/rbac"
"github.com/rancher/shepherd/extensions/kubeapi/namespaces"
"github.com/rancher/shepherd/extensions/kubeapi/projects"
"github.com/rancher/shepherd/extensions/kubeapi/rbac"
"github.com/rancher/shepherd/extensions/kubeapi/workloads/deployments"
"github.com/rancher/shepherd/extensions/kubeconfig"
"github.com/rancher/shepherd/extensions/workloads"
namegen "github.com/rancher/shepherd/pkg/namegenerator"
appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kwait "k8s.io/apimachinery/pkg/util/wait"
)

const (
dummyFinalizer = "dummy"
timeFormat = "2006/01/02 15:04:05"
roleProjectOwner = "project-owner"
roleOwner = "cluster-owner"
dummyFinalizer = "dummy"
timeFormat = "2006/01/02 15:04:05"
projectOwner = "project-owner"
clusterOwner = "cluster-owner"
clusterMember = "cluster-member"
Priyashetty17 marked this conversation as resolved.
Show resolved Hide resolved
systemProjectName = "System"
systemProjectLabel = "authz.management.cattle.io/system-project"
namespaceSteveType = "namespace"
resourceQuotaAnnotation = "field.cattle.io/resourceQuota"
containerDefaultLimitAnnotation = "field.cattle.io/containerDefaultResourceLimit"
resourceQuotaStatusAnnotation = "cattle.io/status"
containerName = "nginx"
imageName = "nginx"
)

var project = v3.Project{
ObjectMeta: metav1.ObjectMeta{
Name: "",
Namespace: "",
Finalizers: []string{},
},
Spec: v3.ProjectSpec{
ClusterName: "",
},
}

var prtb = v3.ProjectRoleTemplateBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "",
Expand All @@ -47,37 +50,106 @@ var prtb = v3.ProjectRoleTemplateBinding{
UserPrincipalName: "",
}

func createProject(client *rancher.Client, clusterName string) (*v3.Project, error) {
project.Name = namegen.AppendRandomString("testproject")
project.Namespace = clusterName
project.Spec.ClusterName = clusterName
createdProject, err := projectsApi.CreateProject(client, &project)
func NewProjectTemplate(clusterID string) *v3.Project {
project := &v3.Project{
ObjectMeta: metav1.ObjectMeta{
Name: namegen.AppendRandomString("testproject"),
Namespace: clusterID,
Finalizers: []string{},
},
Spec: v3.ProjectSpec{
ClusterName: clusterID,
ResourceQuota: &v3.ProjectResourceQuota{
Limit: v3.ResourceQuotaLimit{
Pods: "",
},
},
NamespaceDefaultResourceQuota: &v3.NamespaceResourceQuota{
Limit: v3.ResourceQuotaLimit{
Pods: "",
},
},
ContainerDefaultResourceLimit: &v3.ContainerResourceLimit{
RequestsCPU: "",
RequestsMemory: "",
LimitsCPU: "",
LimitsMemory: "",
},
},
}
return project
}

func createProject(client *rancher.Client, project *v3.Project) (*v3.Project, error) {
createdProject, err := client.WranglerContext.Mgmt.Project().Create(project)
if err != nil {
return nil, err
}

return createdProject, nil
}

func createProjectAndNamespace(client *rancher.Client, clusterID string, project *v3.Project) (*v3.Project, *corev1.Namespace, error) {
createdProject, err := createProject(client, project)
if err != nil {
return nil, nil, err
}

namespaceName := namegen.AppendRandomString("testns-")
createdNamespace, err := namespaces.CreateNamespace(client, clusterID, createdProject.Name, namespaceName, "", map[string]string{}, map[string]string{})
if err != nil {
return nil, nil, err
}

return createdProject, createdNamespace, nil
}

func createProjectRoleTemplateBinding(client *rancher.Client, user *management.User, project *v3.Project, role string) (*v3.ProjectRoleTemplateBinding, error) {
projectName := fmt.Sprintf("%s:%s", project.Namespace, project.Name)
prtb.Name = namegen.AppendRandomString("prtb-")
prtb.Namespace = project.Name
prtb.ProjectName = projectName
prtb.RoleTemplateName = role
prtb.UserPrincipalName = user.PrincipalIDs[0]
createdProjectRoleTemplateBinding, err := rbacApi.CreateProjectRoleTemplateBinding(client, &prtb)

createdProjectRoleTemplateBinding, err := rbac.CreateProjectRoleTemplateBinding(client, &prtb)
if err != nil {
return nil, err
}

return createdProjectRoleTemplateBinding, nil
}

func createDeployment(client *rancher.Client, clusterID string, namespace string, replicaCount int) (*appv1.Deployment, error) {
deploymentName := namegen.AppendRandomString("testdeployment")
containerTemplate := workloads.NewContainer(containerName, imageName, corev1.PullAlways, []corev1.VolumeMount{}, []corev1.EnvFromSource{}, nil, nil, nil)
podTemplate := workloads.NewPodTemplate([]corev1.Container{containerTemplate}, []corev1.Volume{}, []corev1.LocalObjectReference{}, nil)
replicas := int32(replicaCount)

deploymentObj, err := deployments.CreateDeployment(client, clusterID, deploymentName, namespace, podTemplate, replicas)
if err != nil {
return nil, err
}

return deploymentObj, nil
}

func updateProjectNamespaceFinalizer(client *rancher.Client, existingProject *v3.Project, finalizer []string) (*v3.Project, error) {
updatedProject := existingProject.DeepCopy()
updatedProject.ObjectMeta.Finalizers = finalizer

updatedProject, err := projects.UpdateProject(client, existingProject, updatedProject)
if err != nil {
return nil, err
}

return updatedProject, nil
}

func waitForFinalizerToUpdate(client *rancher.Client, projectName string, projectNamespace string, finalizerCount int) error {
err := kwait.Poll(defaults.FiveHundredMillisecondTimeout, defaults.TenSecondTimeout, func() (done bool, pollErr error) {
project, pollErr := projectsApi.ListProjects(client, project.Namespace, metav1.ListOptions{
FieldSelector: "metadata.name=" + project.Name,
project, pollErr := projects.ListProjects(client, projectNamespace, metav1.ListOptions{
FieldSelector: "metadata.name=" + projectName,
})
if pollErr != nil {
return false, pollErr
Expand All @@ -86,7 +158,7 @@ func waitForFinalizerToUpdate(client *rancher.Client, projectName string, projec
if len(project.Items[0].Finalizers) == finalizerCount {
return true, nil
}
return false, nil
return false, pollErr
})

if err != nil {
Expand All @@ -96,7 +168,55 @@ func waitForFinalizerToUpdate(client *rancher.Client, projectName string, projec
return nil
}

func checkPodLogsForErrors(client *rancher.Client, cluster string, podName string, namespace string, errorPattern string, startTime time.Time) error {
func checkAnnotationExistsInNamespace(client *rancher.Client, clusterID string, namespaceName string, annotationKey string, expectedExistence bool) error {
updatedNamespace, err := namespaces.GetNamespaceByName(client, clusterID, namespaceName)
if err != nil {
return err
}

_, exists := updatedNamespace.Annotations[annotationKey]
if (expectedExistence && !exists) || (!expectedExistence && exists) {
errorMessage := fmt.Sprintf("Annotation '%s' should%s exist", annotationKey, map[bool]string{true: "", false: " not"}[expectedExistence])
return errors.New(errorMessage)
}

return nil
}

func checkNamespaceLabelsAndAnnotations(clusterID string, projectName string, namespace *corev1.Namespace) error {
var errorMessages []string
expectedLabels := map[string]string{
projects.ProjectIDAnnotation: projectName,
}

expectedAnnotations := map[string]string{
projects.ProjectIDAnnotation: clusterID + ":" + projectName,
}

for key, value := range expectedLabels {
if _, ok := namespace.Labels[key]; !ok {
errorMessages = append(errorMessages, fmt.Sprintf("expected label %s not present in namespace labels", key))
} else if namespace.Labels[key] != value {
errorMessages = append(errorMessages, fmt.Sprintf("label value mismatch for %s: expected %s, got %s", key, value, namespace.Labels[key]))
}
}

for key, value := range expectedAnnotations {
if _, ok := namespace.Annotations[key]; !ok {
errorMessages = append(errorMessages, fmt.Sprintf("expected annotation %s not present in namespace annotations", key))
} else if namespace.Annotations[key] != value {
errorMessages = append(errorMessages, fmt.Sprintf("annotation value mismatch for %s: expected %s, got %s", key, value, namespace.Annotations[key]))
}
}

if len(errorMessages) > 0 {
return fmt.Errorf(strings.Join(errorMessages, "\n"))
}

return nil
}

func checkPodLogsForErrors(client *rancher.Client, clusterID string, podName string, namespace string, errorPattern string, startTime time.Time) error {
startTimeUTC := startTime.UTC()

errorRegex := regexp.MustCompile(errorPattern)
Expand All @@ -105,7 +225,7 @@ func checkPodLogsForErrors(client *rancher.Client, cluster string, podName strin
var errorMessage string

kwait.Poll(defaults.TenSecondTimeout, defaults.TwoMinuteTimeout, func() (bool, error) {
podLogs, err := kubeconfig.GetPodLogs(client, cluster, podName, namespace, "")
podLogs, err := kubeconfig.GetPodLogs(client, clusterID, podName, namespace, "")
if err != nil {
return false, err
}
Expand Down Expand Up @@ -137,15 +257,3 @@ func checkPodLogsForErrors(client *rancher.Client, cluster string, podName strin

return nil
}

func updateProjectNamespaceFinalizer(client *rancher.Client, existingProject *v3.Project, finalizer []string) (*v3.Project, error) {
updatedProject := existingProject.DeepCopy()
updatedProject.ObjectMeta.Finalizers = finalizer

updatedProject, err := projectsApi.UpdateProject(client, existingProject, updatedProject)
if err != nil {
return nil, err
}

return updatedProject, nil
}