From 81a2c7b2dfed91f5d1ca8626df477608a321baf1 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Thu, 29 Jan 2026 09:00:32 +0100 Subject: [PATCH] Support authentication and TLS in k6 load testing script (#391) --- internal/command/controller/run.go | 9 ++++++++ test/load/vm-lifecycle.js | 34 ++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/internal/command/controller/run.go b/internal/command/controller/run.go index 66fb7b4..d7b0195 100644 --- a/internal/command/controller/run.go +++ b/internal/command/controller/run.go @@ -36,6 +36,7 @@ var experimentalPingInterval time.Duration var deprecatedPrometheusMetrics bool var experimentalDisableDBCompression bool var workerOfflineTimeout time.Duration +var synthetic bool func newRunCommand() *cobra.Command { cmd := &cobra.Command{ @@ -90,6 +91,10 @@ func newRunCommand() *cobra.Command { "of scheduling (no new VMs will be scheduled on such worker and already assigned VMs will be "+ "marked as failed)") + // Hidden flags + cmd.Flags().BoolVar(&synthetic, "synthetic", false, "") + cmd.Flags().MarkHidden("synthetic") + return cmd } @@ -152,6 +157,10 @@ func runController(cmd *cobra.Command, args []string) (err error) { controllerOpts = append(controllerOpts, controller.WithAPIPrefix(apiPrefix)) } + if synthetic { + controllerOpts = append(controllerOpts, controller.WithSynthetic()) + } + var controllerCert tls.Certificate if !noTLS { diff --git a/test/load/vm-lifecycle.js b/test/load/vm-lifecycle.js index 30ae3b8..8368a6c 100644 --- a/test/load/vm-lifecycle.js +++ b/test/load/vm-lifecycle.js @@ -2,12 +2,15 @@ import {check} from 'k6'; import http from 'k6/http'; import {WebSocket} from 'k6/experimental/websockets'; import crypto from 'k6/crypto'; +import encoding from 'k6/encoding'; import {uuidv4} from 'https://jslib.k6.io/k6-utils/1.6.0/index.js'; import {expect} from 'https://jslib.k6.io/k6-testing/0.6.1/index.js'; -const BASE_URL = __ENV.ORCHARD_BASE_URL || 'http://127.0.0.1:6120/v1'; -const WS_BASE_URL = __ENV.ORCHARD_WS_BASE_URL || BASE_URL.replace(/^http/, 'ws'); +const BASE_URL = __ENV.BASE_URL || 'http://127.0.0.1:6120/v1'; +const WS_BASE_URL = __ENV.WS_BASE_URL || BASE_URL.replace(/^http/, 'ws'); const WS_BYTES = __ENV.WS_BYTES || 64 * 1024; +const SERVICE_ACCOUNT_NAME = __ENV.SERVICE_ACCOUNT_NAME; +const SERVICE_ACCOUNT_TOKEN = __ENV.SERVICE_ACCOUNT_TOKEN; export const options = { scenarios: { @@ -51,6 +54,7 @@ function createVM(vmName) { const resp = http.post(`${BASE_URL}/vms`, body, { headers: { 'Content-Type': 'application/json', + ...authHeaders(), }, }); @@ -68,7 +72,11 @@ async function portForward(vmName) { console.debug(`connecting to ${url}`); - const ws = new WebSocket(url); + const ws = new WebSocket(url, [], { + headers: { + ...authHeaders(), + } + }); ws.binaryType = 'arraybuffer'; const sentBytes = new Uint8Array(crypto.randomBytes(WS_BYTES)); @@ -108,7 +116,12 @@ async function portForward(vmName) { } function deleteVM(vmName) { - const resp = http.del(`${BASE_URL}/vms/${vmName}`); + const resp = http.del(`${BASE_URL}/vms/${vmName}`, null, { + headers: { + 'Content-Type': 'application/json', + ...authHeaders(), + } + }); const ok = check(resp, { 'VM deletion succeeded': (r) => r.status === 200, @@ -118,3 +131,16 @@ function deleteVM(vmName) { console.error(`Failed to delete a VM: HTTP ${resp.status}`); } } + +function authHeaders() { + if (!SERVICE_ACCOUNT_NAME || !SERVICE_ACCOUNT_TOKEN) { + return {} + } + + const credentials = `${SERVICE_ACCOUNT_NAME}:${SERVICE_ACCOUNT_TOKEN}`; + const encodedCredentials = encoding.b64encode(credentials); + + return { + Authorization: `Basic ${encodedCredentials}` + } +}