菜单
文档breadcrumb arrow Grafana k6breadcrumb arrow 扩展breadcrumb arrow 创建扩展breadcrumb arrow Secret source 扩展
开源

Secret Source 扩展

Secret source 扩展允许用户编写或使用其他人编写的扩展,以便获取 k6 测试中使用的 Secrets。

JavaScript 扩展类似,Secret source 扩展依赖于扩展作者实现特定的 API。

开始之前

要运行本教程,您需要安装以下应用程序

  • Go
  • Git

您还需要安装 xk6

bash
$ go install go.k6.io/xk6/cmd/xk6@latest

编写一个简单的扩展

  1. 设置工作目录。
bash
$ mkdir xk6-secret-source-cli; cd xk6-secret-source-cli; go mod init xk6-secret-source-cli
  1. Output 扩展的核心是一个实现了 secrets.Source 接口的结构体。

创建一个简单的 Secret source 示例,它只从 CLI flag 读取 Secrets - 类似于内置的 mock 示例。

Go
package cli

import (
	"errors"
	"fmt"
	"strings"

	"go.k6.io/k6/secretsource"
)

func newCLISecretSourceFromParams(params secretsource.Params) (secretsource.Source, error) {
	list := strings.Split(params.ConfigArgument, ",")
	secrets := make(map[string]string, len(list))
	for _, kv := range list {
		k, v, ok := strings.Cut(kv, "=")
		if !ok {
			return nil, fmt.Errorf("parsing %q, needs =", kv)
		}

		secrets[k] = v
	}
	return &cliSecretSource{internal: secrets}
}

type cliSecretSource struct {
	internal map[string]string
}

func (*cliSecretSource) Description() string {
	return "this is an example secret source"
}

func (css *cliSecretSource) Get(key string) (string, error) {
	v, ok := css.internal[key]
	if !ok {
		return "", errors.New("no value")
	}
	return v, nil
}
  1. 注册模块以便在 k6 测试脚本中使用它们。
Go
package cli

import "go.k6.io/k6/secretsource"

// init is called by the Go runtime at application startup.
func init() {
	secretsource.RegisterExtension("cli", newCLISecretSourceFromParams)
}

注意

运行 k6 时,您必须使用 --secret-source flag 进行注册!

最终的扩展代码如下

Go
package cli

import (
	"errors"
	"fmt"
	"strings"

	"go.k6.io/k6/secretsource"
)

// init is called by the Go runtime at application startup.
func init() {
	secretsource.RegisterExtension("cli", newCLISecretSourceFromParams)
}

func newCLISecretSourceFromParams(params secretsource.Params) (secretsource.Source, error) {
	list := strings.Split(params.ConfigArgument, ",")
	secrets := make(map[string]string, len(list))
	for _, kv := range list {
		k, v, ok := strings.Cut(kv, "=")
		if !ok {
			return nil, fmt.Errorf("parsing %q, needs =", kv)
		}

		secrets[k] = v
	}
	return &cliSecretSource{internal: secrets}, nil
}

type cliSecretSource struct {
	internal map[string]string
}

func (*cliSecretSource) Description() string {
	return "this is an example secret source"
}

func (css *cliSecretSource) Get(key string) (string, error) {
	v, ok := css.internal[key]
	if !ok {
		return "", errors.New("no value")
	}
	return v, nil
}

注意以下几点

  • 模块初始化函数 newCLISecretSourceFromParams() 接收 secretsource.Params 的实例。通过此对象,扩展可以访问 Secret source 特定的配置、文件系统接口、CLI 参数、日志记录器等。

  • 本示例中的 Get 函数仅从内部数组返回,但它也可以执行网络请求或任何其他获取 Secrets 所需的操作。

编译您的扩展 k6

要使用此扩展构建 k6 二进制文件,运行

bash
$ go mod tidy # this is needed by the go toolchain
$ xk6 build --with xk6-secret-source-cli=.

注意

xk6-secret-source-cli 是传递给 go mod init 的 Go 模块名称

通常,这将是一个类似于 github.com/grafana/xk6-secret-source-cli 的 URL。

使用您的扩展

现在我们可以使用测试脚本来使用该扩展了。

  1. 在一个新的 JavaScript 文件中,编写一些简单的测试逻辑。
JavaScript
import secrets from 'k6/secrets';

export default async () => {
  const my_secret = await secrets.get('cool'); // get secret from a source with the provided identifier
  console.log(my_secret);
  await secrets.get('else'); // get secret from a source with the provided identifier
  console.log(my_secret); // print the same old secret to see that the secret from above will also be redacted
  console.log('some'); // log the original secret but using its constant value
};
  1. 现在,运行测试。
bash
./k6 run test.js --secret-source=cli=cool=some,else=console --quiet --no-summary

注意

--secret-source=cli=cool=some,else=console 参数告诉 k6 使用您的自定义 Secret source 并提供其配置。--quiet --no-summary flag 配置 k6 只显示自定义输出。

您的输出应类似于以下内容

shell
INFO[0000] ***SECRET_REDACTED***                         source=console
INFO[0000] ***SECRET_REDACTED***                         source="***SECRET_REDACTED***"
INFO[0000] ***SECRET_REDACTED***                         source="***SECRET_REDACTED***"

如您所见,有很多被编辑(隐藏)的 Secrets。并且 console 只有在被访问后才会被编辑,因为在此之前 k6 无法知道它实际上是一个 secret。

注意

在实际应用中,Secrets 预计不会是像本例这样自然出现在 k6 输出中的普通字符串。

注意事项

有问题?欢迎加入 k6 社区论坛 的扩展讨论。