diff --git a/.gitignore b/.gitignore index 2dde72219..c30dbf8f1 100644 --- a/.gitignore +++ b/.gitignore @@ -16,11 +16,12 @@ tofu/main/*/*config # Others scripts/utils/*.txt -scripts/utils/export-metrics/metrics* -scripts/utils/export-metrics/chunks_head -scripts/utils/export-metrics/wal -scripts/utils/export-metrics/queries.active -scripts/utils/export-metrics/*.tar.gz +chunks_head +wal +queries.active +*.tar +*.tar.gz +.env # Binaries /dartboard diff --git a/k6/generic/generic_utils.js b/k6/generic/generic_utils.js index b4e4ac325..7adf3f223 100644 --- a/k6/generic/generic_utils.js +++ b/k6/generic/generic_utils.js @@ -137,3 +137,13 @@ export function getPathBasename(filePath) { // Extract the substring after the last slash return filePath.substring(lastSlashIndex + 1); } + +export function getRandomElements(arr, count) { + const shuffled = [...arr]; + for (let i = shuffled.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; + } + return shuffled.slice(0, count); +} + diff --git a/k6/projects/project_utils.js b/k6/projects/project_utils.js index 3918ac5cc..b640960de 100644 --- a/k6/projects/project_utils.js +++ b/k6/projects/project_utils.js @@ -13,16 +13,22 @@ export const putProjectTag = { url: `/v3/projects/` } export function cleanupMatchingProjects(baseUrl, cookies, namePrefix) { - let res = http.get(`${baseUrl}/${baseProjectsPath}`, { cookies: cookies }) + let res = http.get(`${baseUrl}/${normanProjectsPath}`, { + headers: { + accept: "application/json", + 'content-type': "application/json", + }, + cookies: cookies }) check(res, { - '/v1/management.cattle.io.projects returns status 200': (r) => r.status === 200, + 'GET /v3/projects returns status 200': (r) => r.status === 200, }) - JSON.parse(res.body)["data"].filter(r => r["spec"]["displayName"].startsWith(namePrefix)).forEach(r => { + JSON.parse(res.body)["data"].filter(r => r["name"].startsWith(namePrefix)).forEach(r => { res = http.del(`${baseUrl}/${normanProjectsPath}/${r["id"]}`, { cookies: cookies }) check(res, { 'DELETE /v3/projects returns status 200': (r) => r.status === 200, }) }) + return res } export function getProject(baseUrl, cookies, id) { @@ -52,7 +58,7 @@ export function getNormanProjects(baseUrl, cookies) { return { res: res, projectArray: projectArray } } -export function createNormanProject(baseUrl, body, cookies) { +export function createNormanProject(baseUrl, cookies, body) { const res = http.post( `${baseUrl}/${normanProjectsPath}`, body, diff --git a/k6/rancher/rancher_users_utils.js b/k6/rancher/rancher_users_utils.js index b2c738635..96bba2eeb 100644 --- a/k6/rancher/rancher_users_utils.js +++ b/k6/rancher/rancher_users_utils.js @@ -52,7 +52,7 @@ export function setUserPreferences(baseUrl, cookies, userId, userPreferences) { export function getPrincipalIds(baseUrl, cookies) { const response = http.get( `${baseUrl}/v1/management.cattle.io.users`, - { cookies: cookies } + { headers: { accept: 'application/json' }, cookies: cookies } ) if (response.status !== 200) { fail('could not list users') @@ -64,7 +64,7 @@ export function getPrincipalIds(baseUrl, cookies) { export function getPrincipalById(baseUrl, cookies, id) { const response = http.get( `${baseUrl}/v3/principals/${id}`, - { cookies: cookies } + { headers: { accept: 'application/json' }, cookies: cookies } ) if (response.status !== 200) { fail('could not get principal by ID') @@ -82,7 +82,7 @@ export function getNormanUsers(baseUrl, params = null) { export function getCurrentUserPrincipal(baseUrl, cookies) { const response = http.get( `${baseUrl}/v3/principals?me=true`, - { cookies: cookies } + { headers: { accept: 'application/json' }, cookies: cookies } ) if (response.status !== 200) { fail('could not get current User\'s Principal') @@ -93,7 +93,7 @@ export function getCurrentUserPrincipal(baseUrl, cookies) { export function getCurrentUserPrincipalId(baseUrl, cookies) { const response = http.get( `${baseUrl}/v3/users?me=true`, - { cookies: cookies } + { headers: { accept: 'application/json' }, cookies: cookies } ) if (response.status !== 200) { fail('could not get my user') @@ -104,7 +104,7 @@ export function getCurrentUserPrincipalId(baseUrl, cookies) { export function getClusterIds(baseUrl, cookies) { const response = http.get( `${baseUrl}/v1/management.cattle.io.clusters`, - { cookies: cookies } + { headers: { accept: 'application/json' }, cookies: cookies } ) if (response.status !== 200) { fail('could not list clusters') @@ -146,7 +146,7 @@ export function getUsers(baseUrl, cookies) { } export function getUser(baseUrl, cookies, userId) { - const res = http.get(`${baseUrl}/v1/management.cattle.io.users/${userId}`, { cookies: cookies }) + const res = http.get(`${baseUrl}/v1/management.cattle.io.users/${userId}`, { headers: { accept: 'application/json' }, cookies: cookies }) check(res, { '/v1/management.cattle.io.users/ returns status 200': (r) => r.status === 200 || r.status === 204, }) @@ -154,7 +154,7 @@ export function getUser(baseUrl, cookies, userId) { } export function deleteUser(baseUrl, cookies, userId) { - const res = http.del(`${baseUrl}/v3/users/${userId}`, { cookies: cookies }) + const res = http.del(`${baseUrl}/v3/users/${userId}`, { headers: { accept: 'application/json' }, cookies: cookies }) check(res, { 'DELETE /v3/users returns status 200': (r) => r.status === 200 || r.status === 204, }) diff --git a/k6/rancher/rancher_utils.js b/k6/rancher/rancher_utils.js index 533fef315..5f56c7f60 100644 --- a/k6/rancher/rancher_utils.js +++ b/k6/rancher/rancher_utils.js @@ -10,18 +10,23 @@ export function getCookies(baseUrl) { } export function login(baseUrl, cookies, username, password) { + const params = { + headers: { + accept: 'application/json', + 'content-type': 'application/json; charset=UTF-8', + }, + } + + // Only add cookies if they exist and are not empty + if (cookies && Object.keys(cookies).length > 0) { + console.log("Using cookies, count:", Object.keys(cookies).length) + params.cookies = cookies + } const response = http.post( `${baseUrl}/v3-public/localProviders/local?action=login`, JSON.stringify({ "description": "UI session", "responseType": "cookie", "username": username, "password": password }), - { - headers: { - accept: 'application/json', - 'content-type': 'application/json; charset=UTF-8', - }, - cookies: { cookies }, - } + params ) - console.log("POST login: ", response.status); check(response, { 'login works': (r) => r.status === 200 || r.status === 401, @@ -372,6 +377,32 @@ export function createImportedCluster(baseUrl, cookies, name) { }) } +export function getProvisioningClusters(baseUrl, cookies) { + const response = http.get(`${baseUrl}/v1/provisioning.cattle.io.clusters?pagesize=100000&exclude=metadata.managedFields`, { + headers: { + accept: 'application/json', + }, + cookies: cookies, + }) + check(response, { + 'GET v1/provisioning.cattle.io.clusters returns status 200': (r) => r.status === 200, + }) + return response +} + +export function getManagementClusters(baseUrl, cookies) { + const response = http.get(`${baseUrl}/v1/management.cattle.io.clusters?pagesize=100000&exclude=metadata.managedFields`, { + headers: { + accept: 'application/json', + }, + cookies: cookies, + }) + check(response, { + 'GET v1/management.cattle.io.clusters returns status 200': (r) => r.status === 200, + }) + return response +} + export function logout(baseUrl, cookies) { const response = http.post(`${baseUrl}/v3/tokens?action=logout`, '{}', { headers: { @@ -384,6 +415,8 @@ export function logout(baseUrl, cookies) { check(response, { 'logging out works': (r) => r.status === 200, }) + + return response } export function generateAuthorizationHeader(token) { diff --git a/k6/rbac/create_RTBs.js b/k6/rbac/create_RTBs.js index 330055db1..7ae5f823e 100644 --- a/k6/rbac/create_RTBs.js +++ b/k6/rbac/create_RTBs.js @@ -1,18 +1,26 @@ import { check, fail, sleep } from 'k6'; -import exec from 'k6/execution'; import http from 'k6/http'; -import { randomUUID } from 'k6/crypto'; import { Trend } from 'k6/metrics'; +import { vu as metaVU } from 'k6/execution' +import * as k6Util from "../generic/k6_utils.js"; import { - getCookies, login, logout, deleteProjectsByPrefix, createProject, - listProjects, getProjectById, getRandomElements + getCookies, login, logout, getManagementClusters } from "../rancher/rancher_utils.js"; +import { getRandomElements } from "../generic/generic_utils.js"; +import { getClusterIds, getCurrentUserPrincipalId, getPrincipalIds } from "../rancher/rancher_users_utils.js"; import { - createUser, listUsers, listRoles, listRoleTemplates, + createNormanProject as createProject, + getProjects as listProjects, + getProject as getProjectById, + cleanupMatchingProjects as deleteProjectsByPrefix +} from "../projects/project_utils.js"; +import { + createUser, listRoles, listRoleTemplates, listRoleBindings, listClusterRoles, listClusterRoleBindings, listCRTBs, listPRTBs, deleteRoleTemplatesByPrefix, deleteUsersByPrefix, createRoleTemplate, createPRTB, createCRTB, - deletePRTBsByDescriptionLabel, deleteCRTBsByDescriptionLabel + deletePRTBsByDescriptionLabel, deleteCRTBsByDescriptionLabel, + createGlobalRoleBinding } from './rbac_utils.js'; // Parameters @@ -20,13 +28,19 @@ const vus = __ENV.VUS || 5 const projectCount = Number(__ENV.PROJECT_COUNT) || 10 const userCount = Number(__ENV.USER_COUNT) || 10 const testUserPassword = __ENV.TEST_USER_PASSWORD -const userPrefix = __ENV.USER_PREFIX || 'test-user' +const testPrefix = "create-RTBs" +const userPrefix = `${testPrefix}-${__ENV.USER_PREFIX || 'test-user'}` +const projectsPrefix = `${testPrefix}-rtbs-test` +const projectRoleTemplatePrefix = `${testPrefix}-Dartboard-PRTB` +const clusterRoleTemplatePrefix = `${testPrefix}-Dartboard-CRTB` // Option setting const baseUrl = __ENV.BASE_URL const username = __ENV.USERNAME const password = __ENV.PASSWORD +export const handleSummary = k6Util.customHandleSummary; + // Option setting export const options = { insecureSkipTLSVerify: true, @@ -68,7 +82,7 @@ const numPRTBsTrend = new Trend('num_prtbs'); // Test functions, in order of execution export function setup() { // log in - if (!login(baseUrl, {}, username, password)) { + if (login(baseUrl, null, username, password).status !== 200) { fail(`could not login to cluster`) } const cookies = getCookies(baseUrl) @@ -76,88 +90,95 @@ export function setup() { // delete leftovers, if any cleanup(cookies) - let clusterIds = getClusterIds(cookies) + let clusterIds = getClusterIds(baseUrl, cookies) let clusterId = getRandomElements(clusterIds, 1)[0] console.log(`Utilizing Cluster with the ID ${clusterId}`) - let myId = getMyId(cookies) + + const clustersResponse = getManagementClusters(baseUrl, cookies) + if (clustersResponse.status === 200) { + const clusters = JSON.parse(clustersResponse.body).data + const cluster = clusters.find(c => c.id === clusterId) + if (cluster) { + console.log(`Selected Cluster Name: ${cluster.spec.displayName}`) + } + } + let myId = getCurrentUserPrincipalId(baseUrl, cookies) // Create Projects, and Users - for (let numProjects = 0; numProjects < projectCount; numProjects++) { - let res = createProject(baseUrl, cookies, `Test Project ${numProjects + 1}`, clusterId, myId) + for (let projectNum = 0; projectNum < projectCount; projectNum++) { + const projectName = `${projectsPrefix}-vu${metaVU.idInInstance}-${projectNum.toString().padStart(4, '0')}` + const projectBody = JSON.stringify({ + type: "project", + name: projectName, + description: `Load test project ${projectNum + 1}`, + clusterId: "local", + creatorId: myId, + }) + let res = createProject(baseUrl, cookies, projectBody) if (res.status !== 201) { console.log("create project status: ", res.status) fail("Failed to create all expected Projects") } } + // Store created users with their credentials for later use + let createdUsers = [] for (let numUsers = 0; numUsers < userCount; numUsers++) { - const userName = `${userPrefix}-${randomUUID()}`; - let res = createUser(baseUrl, cookies, `Test User ${numUsers + 1}`, userName, testUserPassword) + const userName = `${userPrefix}-${crypto.randomUUID()}`; + let res = createUser(baseUrl, cookies, `Dartboard Test User ${numUsers + 1}`, userPrefix, userName, testUserPassword) if (res.status !== 201) { console.log("create user status: ", res.status) fail("Failed to create all expected Users") } + + const userData = JSON.parse(res.body) + createdUsers.push({ + id: userData.id, + username: userName + }) + + // Add GlobalRoleBinding so user can log in + const userId = userData.id + res = createGlobalRoleBinding(baseUrl, { cookies: cookies }, userId, "user") + if (res.status !== 201 && res.status !== 204) { + console.log("create globalrolebinding status: ", res.status) + fail("Failed to create GlobalRoleBinding for user") + } } - let projectsRes = listProjects(baseUrl, cookies) + // Wait for GlobalRoleBindings to propagate before continuing + console.log("Waiting for GlobalRoleBindings to propagate...") + sleep(5) + + let {res: projectsRes, projectArray} = listProjects(baseUrl, cookies) if (projectsRes.status !== 200) { fail("Failed to retrieve Projects") } - let usersRes = listUsers(baseUrl, cookies) - if (usersRes.status !== 200) { - fail("Failed to retrieve Users") - } - let projects = JSON.parse(projectsRes.body)["data"].filter(p => ("displayName" in p["spec"]) && p["spec"]["displayName"].startsWith("Test ")) - let users = JSON.parse(usersRes.body)["data"].filter(p => ("name" in p) && p["name"].startsWith("Test ")) + let projects = projectArray.filter(p => ("spec" in p) && ("displayName" in p["spec"]) && p["spec"]["displayName"].startsWith(projectsPrefix)) + + console.log(`Found ${projects.length} projects matching prefix "${projectsPrefix}"`) + console.log(`Created ${createdUsers.length} users`) + + if (projects.length === 0) { + fail(`No projects found matching prefix "${projectsPrefix}"`) + } + if (createdUsers.length === 0) { + fail(`No users were created`) + } updateRBACNumbers(cookies) // return data that remains constant throughout the test return { cookies: cookies, - principalIds: getPrincipalIds(cookies), + principalIds: getPrincipalIds(baseUrl, cookies), myId: myId, // clusterIds: clusterIds, clusterId: clusterId, projects: projects, - users: users, - } -} - -function getPrincipalIds(cookies) { - const response = http.get( - `${baseUrl}/v1/management.cattle.io.users`, - { cookies: cookies } - ) - if (response.status !== 200) { - fail('could not list users') - } - const users = JSON.parse(response.body).data - return users.filter(u => u["username"] != null).map(u => u["principalIds"][0]) -} - -function getMyId(cookies) { - const response = http.get( - `${baseUrl}/v3/users?me=true`, - { cookies: cookies } - ) - if (response.status !== 200) { - fail('could not get my user') + users: createdUsers, // Use the users we just created with known credentials } - return JSON.parse(response.body).data[0].principalIds[0] -} - -function getClusterIds(cookies) { - const response = http.get( - `${baseUrl}/v1/management.cattle.io.clusters`, - { cookies: cookies } - ) - if (response.status !== 200) { - fail('could not list clusters') - } - const clusters = JSON.parse(response.body).data - return clusters.map(c => c["id"]) } // updates count for each of the relevant RBAC metrics @@ -191,14 +212,21 @@ function updateRBACNumbers(cookies) { } function cleanup(cookies) { - let success = false - let projectsDeleted = deleteProjectsByPrefix(baseUrl, cookies, "Dartboard ") - let usersDeleted = deleteUsersByPrefix(baseUrl, cookies, "Dartboard ") - let prtbsDeleted = deletePRTBsByDescriptionLabel(baseUrl, cookies) - let crtbsDeleted = deleteCRTBsByDescriptionLabel(baseUrl, cookies) - let roleTemplatesDeleted = deleteRoleTemplatesByPrefix(baseUrl, cookies, "Dartboard ") + console.log(`Cleaning up Projects, Users, Role Templates, CRTBs, and PRTBs with description label starting with test prefixes`) + let projectsDeleted = deleteProjectsByPrefix(baseUrl, cookies, projectsPrefix) + // Use "Dartboard" prefix to match the description format "Dartboard Test X" + let usersDeleted = deleteUsersByPrefix(baseUrl, cookies, userPrefix) + let prtbsDeleted = deletePRTBsByDescriptionLabel(baseUrl, cookies, projectRoleTemplatePrefix) + let crtbsDeleted = deleteCRTBsByDescriptionLabel(baseUrl, cookies, clusterRoleTemplatePrefix) + let roleTemplatesDeleted = deleteRoleTemplatesByPrefix(baseUrl, cookies, projectRoleTemplatePrefix) if (!projectsDeleted || !usersDeleted || !roleTemplatesDeleted || !prtbsDeleted || !crtbsDeleted) { + console.log("Projects deleted status: ", projectsDeleted) + console.log("Users deleted status: ", usersDeleted) + console.log("Role Templates deleted status: ", roleTemplatesDeleted) + console.log("PRTBs deleted status: ", prtbsDeleted) + console.log("CRTBs deleted status: ", crtbsDeleted) + // Fail the test if any cleanup operation did not complete successfully fail("failed to delete all objects created by test") } } @@ -214,7 +242,11 @@ function createUserExpectFail(baseUrl, cookies, name, password = "useruseruser") "password": password, "username": `user-${userName}` }), - { cookies: cookies } + { + cookies: cookies, + // prevent k6 from marking non-2xx responses as failed requests for this request, since we're explicitly testing for failure + responseCallback: http.expectedStatuses(401, 403) + } ) let checkOK = check(res, { @@ -265,7 +297,11 @@ function createProjectExpectFail(baseUrl, cookies, name, clusterId, userPrincipa } } }), - { cookies: cookies } + { + cookies: cookies, + // prevent k6 from marking non-2xx responses as failed requests for this request, since we're explicitly testing for failure + responseCallback: http.expectedStatuses(401, 403) + } ) let checkOK = check(res, { @@ -275,6 +311,7 @@ function createProjectExpectFail(baseUrl, cookies, name, clusterId, userPrincipa let projectData = JSON.parse(res.body) if (!checkOK || projectData.length > 0) { + console.log("\nResponse post-verify project creation: ", JSON.stringify(res, null, 2), "\n") fail("Status check failed or received unexpected Project data") } @@ -282,12 +319,27 @@ function createProjectExpectFail(baseUrl, cookies, name, clusterId, userPrincipa } export function createPRTBs(data) { - const i = exec.scenario.iterationInTest + const iterationIndex = __ITER % data.projects.length + const project = data.projects[iterationIndex] + + if (!project) { + console.log(`No project found at index ${iterationIndex}, projects length: ${data.projects.length}`) + return + } + + // Use modulo to get user index, ensuring we don't go out of bounds + const userIndex = __ITER % data.users.length + let user = data.users[userIndex] + + if (!user) { + console.log(`No user found at index ${userIndex}, users length: ${data.users.length}`) + return + } let projectRoleTemplate = { "type": "roleTemplate", - "name": `Dartboard PRTB ${i}`, - "description": `Dartboard Test Project RT ${i}`, + "name": `${projectRoleTemplatePrefix} ${iterationIndex}`, + "description": `${projectRoleTemplatePrefix} ${iterationIndex}`, "rules": [ { "apiGroups": [ @@ -318,27 +370,30 @@ export function createPRTBs(data) { } let roleTemplateId = JSON.parse(res.body).id - let user = data.users[i] - res = createPRTB(baseUrl, data.cookies, data.projects[i].id, roleTemplateId, user.id) + const projectId = project.id.replace("/", ":") - if (res.status !== 201) { - console.log("\nResponse: ", JSON.stringify(res, null, 2), "\n") - fail("Failed to create PRTB") - } + res = createPRTB(baseUrl, data.cookies, projectId, roleTemplateId, user.id, projectRoleTemplatePrefix) + check(res, { + 'PRTB post returns 201 (created)': (r) => r.status === 201, + }) // log in as user - if (!login(baseUrl, {}, user.username, testUserPassword)) { - fail(`could not login to cluster as ${user.username}`) + let loginRes = login(baseUrl, {}, user.username, testUserPassword) + if (!loginRes || loginRes.status !== 200) { + console.warn(`could not login to cluster as ${user.username}, status: ${loginRes ? loginRes.status : 'unknown'}`) + return // Don't fail, just skip verification for this iteration } const cookies = getCookies(baseUrl) // updateRBACNumbers with admin cookies updateRBACNumbers(data.cookies) - - getProjectById(baseUrl, cookies, data.projects[i].id.replace("/", ":")) + + // verify permissions with user cookies + getProjectById(baseUrl, cookies, data.projects[iterationIndex].id.replace("/", ":")) listProjects(baseUrl, cookies) - createProjectExpectFail(baseUrl, cookies, `Test Create Project Should Fail ${i}`, data.clusterId, user.id) + const projectName = `${projectsPrefix}-should-fail-vu${metaVU.idInInstance}-${iterationIndex.toString().padStart(4, '0')}` + createProjectExpectFail(baseUrl, cookies, projectName, data.clusterId, user.id) res = logout(baseUrl, cookies); if (res.status !== 200) { @@ -348,12 +403,21 @@ export function createPRTBs(data) { } export function createCRTBs(data) { - const i = exec.scenario.iterationInTest + const iterationIndex = __ITER % data.users.length + + // Use modulo to get user index + const userIndex = __ITER % data.users.length + let user = data.users[userIndex] + + if (!user) { + console.log(`No user found at index ${userIndex}, users length: ${data.users.length}`) + return + } let clusterRoleTemplate = { "type": "roleTemplate", - "name": `Dartboard CRTB ${i}`, - "description": `Dartboard Test Cluster RT ${i}`, + "name": `${clusterRoleTemplatePrefix} ${iterationIndex}`, + "description": `${clusterRoleTemplatePrefix} ${iterationIndex}`, "rules": [ { "apiGroups": [ @@ -384,27 +448,31 @@ export function createCRTBs(data) { } let roleTemplateId = JSON.parse(res.body).id - let user = data.users[i] res = createCRTB(baseUrl, data.cookies, data.clusterId, roleTemplateId, user.id) + check(res, { + 'CRTB post returns 201 (created)': (r) => r.status === 201, + }) - if (res.status !== 201) { - console.log("\nResponse: ", JSON.stringify(res, null, 2), "\n") - fail("Failed to create CRTB") - } - - // log in as user - if (!login(baseUrl, {}, user.username, testUserPassword)) { - fail(`could not login to cluster as ${user.username}`) + // log in as user + let loginRes = login(baseUrl, {}, user.username, testUserPassword) + if (!loginRes || loginRes.status !== 200) { + console.warn(`could not login to cluster as ${user.username}, status: ${loginRes ? loginRes.status : 'unknown'}`) + return // Don't fail, just skip verification for this iteration } const cookies = getCookies(baseUrl) // updateRBACNumbers with admin cookies updateRBACNumbers(data.cookies) - getProjectById(baseUrl, cookies, data.projects[i].id.replace("/", ":")) + // Get a project index safely + const projectIndex = __ITER % data.projects.length + + // verify permissions with user cookies + getProjectById(baseUrl, cookies, data.projects[projectIndex].id.replace("/", ":")) listProjects(baseUrl, cookies) - createProjectExpectFail(baseUrl, cookies, `Test Create Project Should Fail ${i}`, data.clusterId, user.id) + const projectName = `${projectsPrefix}-should-fail-vu${metaVU.idInInstance}-${iterationIndex.toString().padStart(4, '0')}` + createProjectExpectFail(baseUrl, cookies, projectName, data.clusterId, user.id) res = logout(baseUrl, cookies); if (res.status !== 200) { diff --git a/k6/rbac/rbac_utils.js b/k6/rbac/rbac_utils.js index 5262918b8..3c6ae7037 100644 --- a/k6/rbac/rbac_utils.js +++ b/k6/rbac/rbac_utils.js @@ -2,20 +2,23 @@ import { check, fail } from 'k6'; import http from 'k6/http'; /* - Usernames are prefixed with "user", password defaults to "useruseruser" if not set + Username defaults to "test-user" and password defaults to "useruseruser" if not set */ -export function createUser(baseUrl, cookies, displayName, userName, password = "useruseruser") { +export function createUser(baseUrl, cookies, displayName, description = `Dartboard ${displayName}`, userName = "test-user", password = "useruseruser") { const res = http.post(`${baseUrl}/v3/users`, JSON.stringify({ "type": "user", "name": displayName, - "description": `Dartboard ${displayName}`, + "description": description, "enabled": true, "mustChangePassword": false, "password": password, - "username": `user-${userName}` + "username": `${userName}` }), - { cookies: cookies } + { + headers: { accept: "application/json", "content-type": "application/json" }, + cookies: cookies + } ) check(res, { @@ -54,7 +57,7 @@ export function listUsers(baseUrl, cookies) { fail("Status check failed or did not receive list of Users data") } - return res + return { res: res, usersData: usersData } } export function listRoleTemplates(baseUrl, cookies) { @@ -274,13 +277,13 @@ export function createGlobalRoleBinding(baseUrl, params, userId, roles = ["user" } -export function createPRTB(baseUrl, cookies, projectId, roleTemplateId, userId) { +export function createPRTB(baseUrl, cookies, projectId, roleTemplateId, userId, description = "Dartboard") { const res = http.post( `${baseUrl}/v3/projectroletemplatebindings`, JSON.stringify({ "type": "projectroletemplatebinding", "labels": { - "description": "Dartboard" + "description": description }, "roleTemplateId": roleTemplateId, "userPrincipalId": `local://${userId}`, @@ -332,13 +335,13 @@ export function createCRTB(baseUrl, cookies, clusterId, roleTemplateId, userId) export function deleteUsersByPrefix(baseUrl, cookies, prefix = "Dartboard ") { let deletedAll = true - let res = listUsers(baseUrl, cookies) + let {res: res, usersData: usersData} = listUsers(baseUrl, cookies) if (res.status !== 200) { console.log("list users status: ", res.status) return false } - JSON.parse(res.body)["data"].filter(r => ("description" in r) && r["description"].startsWith(prefix)).forEach(r => { + usersData.filter(r => ("description" in r) && r["description"].startsWith(prefix)).forEach(r => { res = http.del(`${baseUrl}/v3/users/${r["id"]}`, { cookies: cookies }) if (res.status !== 200 && res.status !== 204) { @@ -403,7 +406,7 @@ export function deleteRoleTemplatesByPrefix(baseUrl, cookies, prefix = "Dartboar return deletedAll } -export function deleteCRTBsByDescriptionLabel(baseUrl, cookies, label = { "description": "Dartboard" }) { +export function deleteCRTBsByDescriptionLabel(baseUrl, cookies, label = "Dartboard") { let deletedAll = true let res = listCRTBs(baseUrl, cookies) @@ -412,7 +415,7 @@ export function deleteCRTBsByDescriptionLabel(baseUrl, cookies, label = { "descr return false } - JSON.parse(res.body)["data"].filter(r => ("labels" in r) && ("description" in r["labels"]) && r["labels"].description == label["description"]).forEach(r => { + JSON.parse(res.body)["data"].filter(r => ("labels" in r) && ("description" in r["labels"]) && r["labels"].description == label).forEach(r => { res = http.del(`${baseUrl}/v3/clusterroletemplatebindings/${r["id"]}`, { cookies: cookies }) @@ -429,7 +432,7 @@ export function deleteCRTBsByDescriptionLabel(baseUrl, cookies, label = { "descr return deletedAll } -export function deletePRTBsByDescriptionLabel(baseUrl, cookies, label = { "description": "Dartboard" }) { +export function deletePRTBsByDescriptionLabel(baseUrl, cookies, label = "Dartboard") { let deletedAll = true let res = listPRTBs(baseUrl, cookies) @@ -438,7 +441,7 @@ export function deletePRTBsByDescriptionLabel(baseUrl, cookies, label = { "descr return false } - JSON.parse(res.body)["data"].filter(r => ("labels" in r) && ("description" in r["labels"]) && r["labels"].description == label["description"]).forEach(r => { + JSON.parse(res.body)["data"].filter(r => ("labels" in r) && ("description" in r["labels"]) && r["labels"].description == label).forEach(r => { res = http.del(`${baseUrl}/v3/projectroletemplatebindings/${r["id"]}`, { cookies: cookies }) diff --git a/k6/tests/load_projects_rbac.js b/k6/tests/load_projects_rbac.js index 0cd9993de..60f21cbbf 100644 --- a/k6/tests/load_projects_rbac.js +++ b/k6/tests/load_projects_rbac.js @@ -403,9 +403,9 @@ function getProjectWithRetry(baseUrl, cookies, projectId, maxRetries = 5) { return {} } -function createNormanProjectWithRetry(baseUrl, projectBody, cookies, maxRetries = 5) { +function createNormanProjectWithRetry(baseUrl, cookies, projectBody, maxRetries = 5) { for (let retry = 0; retry < maxRetries; retry++) { - const res = projectUtil.createNormanProject(baseUrl, projectBody, cookies) + const res = projectUtil.createNormanProject(baseUrl, cookies, projectBody) if (res.status === 201) { return res } @@ -435,7 +435,7 @@ function createProjectsAndNamespaces(data, startIndex, endIndex) { }) console.log(`Creating project ${i + 1}/${projectCount}: ${projectName}`) - const projectRes = createNormanProjectWithRetry(baseUrl, projectBody, data.adminCookies, 5) + const projectRes = createNormanProjectWithRetry(baseUrl, data.adminCookies, projectBody, 5) if (projectRes.status === 201) { const projectData = JSON.parse(projectRes.body) diff --git a/k6/vai/filter_change_configmaps.js b/k6/vai/filter_change_configmaps.js index 70b66de01..a870099ca 100644 --- a/k6/vai/filter_change_configmaps.js +++ b/k6/vai/filter_change_configmaps.js @@ -239,7 +239,7 @@ export function setup() { containerDefaultResourceLimit: {}, namespaceDefaultResourceQuota: {} }) - let projRes = projectsUtil.createNormanProject(baseUrl, projectBody, cookies) + let projRes = projectsUtil.createNormanProject(baseUrl, cookies, projectBody) if (projRes.status !== 201) { fail("Dartboard test project not created") }