diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5f7c27909..f14865a17 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,9 +31,9 @@ jobs: with: go-version-file: go.mod - name: golangci-lint - uses: golangci/golangci-lint-action@v8.0.0 + uses: golangci/golangci-lint-action@v9.2.0 with: - version: v2.4.0 + version: latest skip-cache: true contract-validation: diff --git a/Dockerfile b/Dockerfile index 7e4a2c677..54390d842 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM ubuntu:22.10 AS user # Create a nonroot user for final image RUN useradd -u 10001 nonroot -FROM golang:1.25.8-alpine3.22 AS builder +FROM golang:1.26.1-alpine3.22 AS builder WORKDIR /workspace @@ -31,7 +31,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \ -X \"github.com/pluralsh/plural-cli/pkg/common.Date=${APP_DATE}\"" \ -o plural ./cmd/plural -FROM golang:1.25.8-alpine3.22 AS final +FROM golang:1.26.1-alpine3.22 AS final WORKDIR / diff --git a/cmd/command/cd/cd_services.go b/cmd/command/cd/cd_services.go index 4b1c55456..81665940d 100644 --- a/cmd/command/cd/cd_services.go +++ b/cmd/command/cd/cd_services.go @@ -2,19 +2,14 @@ package cd import ( "fmt" - iofs "io/fs" - "os" "path/filepath" - "sort" "strings" "github.com/pluralsh/console/go/polly/fs" "github.com/pluralsh/plural-cli/pkg/common" - lua "github.com/yuin/gopher-lua" gqlclient "github.com/pluralsh/console/go/client" "github.com/pluralsh/console/go/polly/containers" - "github.com/pluralsh/console/go/polly/luautils" "github.com/pluralsh/plural-cli/pkg/cd/template" "github.com/pluralsh/plural-cli/pkg/console" "github.com/pluralsh/plural-cli/pkg/utils" @@ -139,6 +134,10 @@ func (p *Plural) cdServiceCommands() []cli.Command { Name: "context", Usage: "A yaml context file to imitate the internal service template context", }, + cli.StringFlag{ + Name: "service", + Usage: "The service which context to use. Use @{cluster-handle}/{service-name} format.", + }, cli.StringFlag{ Name: "dir", Usage: "The directory to run the lua script from, defaults to the current working directory", @@ -287,7 +286,7 @@ func (p *Plural) handleTemplateService(c *cli.Context) error { } if identifier := c.String("service"); identifier != "" { - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(identifier) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(identifier) if err != nil { return err } @@ -319,126 +318,6 @@ func (p *Plural) handleTemplateService(c *cli.Context) error { return printResult(res) } -func (p *Plural) handleLuaTemplate(c *cli.Context) error { - if err := p.InitConsoleClient(consoleToken, consoleURL); err != nil { - return err - } - - luaFile := c.String("lua-file") - luaDir := c.String("lua-dir") - context := c.String("context") - dir := c.String("dir") - if dir == "" { - dir = "." - } - - if luaFile == "" { - return fmt.Errorf("expected --lua-file flag") - } - - luaStr, err := utils.ReadFile(luaFile) - if err != nil { - return err - } - - if luaDir != "" { - luaFiles, err := luaFolder(luaDir) - if err != nil { - return err - } - - luaStr = luaFiles + "\n\n" + luaStr - } - - ctx := map[string]interface{}{} - if context != "" { - if err := utils.YamlFile(context, &ctx); err != nil { - return err - } - } - - values := map[interface{}]interface{}{} - valuesFiles := []string{} - - dir, err = filepath.Abs(dir) - if err != nil { - return err - } - L := luautils.NewLuaState(dir) - defer L.Close() - - // Register global values and valuesFiles in Lua - valuesTable := L.NewTable() - L.SetGlobal("values", valuesTable) - - valuesFilesTable := L.NewTable() - L.SetGlobal("valuesFiles", valuesFilesTable) - L.SetGlobal("cluster", luautils.GoValueToLuaValue(L, ctx["cluster"])) - L.SetGlobal("configuration", luautils.GoValueToLuaValue(L, ctx["configuration"])) - L.SetGlobal("contexts", luautils.GoValueToLuaValue(L, ctx["contexts"])) - L.SetGlobal("imports", luautils.GoValueToLuaValue(L, ctx["imports"])) - - if err := L.DoString(luaStr); err != nil { - return err - } - - if err := luautils.MapLua(L.GetGlobal("values").(*lua.LTable), &values); err != nil { - return err - } - - if err := luautils.MapLua(L.GetGlobal("valuesFiles").(*lua.LTable), &valuesFiles); err != nil { - return err - } - - result := map[string]interface{}{ - "values": luautils.SanitizeValue(values), - "valuesFiles": valuesFiles, - } - - utils.Highlight("Final lua output:\n\n") - utils.NewYAMLPrinter(result).PrettyPrint() - return nil -} - -func luaFolder(folder string) (string, error) { - luaFiles := make([]string, 0) - if err := filepath.WalkDir(folder, func(path string, info iofs.DirEntry, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - - if strings.HasSuffix(info.Name(), ".lua") { - luaPath, err := filepath.Rel(folder, path) - if err != nil { - return err - } - luaFiles = append(luaFiles, luaPath) - } - - return nil - }); err != nil { - return "", fmt.Errorf("failed to walk lua folder %s: %w", folder, err) - } - - sort.Slice(luaFiles, func(i, j int) bool { - return luaFiles[i] < luaFiles[j] - }) - - luaFileContents := make([]string, 0) - for _, file := range luaFiles { - luaContents, err := os.ReadFile(file) - if err != nil { - return "", fmt.Errorf("failed to read lua file %s: %w", file, err) - } - luaFileContents = append(luaFileContents, string(luaContents)) - } - - return strings.Join(luaFileContents, "\n\n"), nil -} - func (p *Plural) handleCloneClusterService(c *cli.Context) error { if err := p.InitConsoleClient(consoleToken, consoleURL); err != nil { return err @@ -452,7 +331,7 @@ func (p *Plural) handleCloneClusterService(c *cli.Context) error { return fmt.Errorf("could not find cluster %s", c.Args().Get(0)) } - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(1)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(1)) if err != nil { return err } @@ -498,7 +377,7 @@ func (p *Plural) handleUpdateClusterService(c *cli.Context) error { return err } contextBindings := containers.NewSet[string]() - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(0)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(0)) if err != nil { return err } @@ -615,7 +494,7 @@ func (p *Plural) handleDescribeClusterService(c *cli.Context) error { return err } - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(0)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(0)) if err != nil { return err } @@ -651,7 +530,7 @@ func (p *Plural) handleDeleteClusterService(c *cli.Context) error { if err := p.InitConsoleClient(consoleToken, consoleURL); err != nil { return err } - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(0)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(0)) if err != nil { return err } @@ -677,7 +556,7 @@ func (p *Plural) handleKickClusterService(c *cli.Context) error { if err := p.InitConsoleClient(consoleToken, consoleURL); err != nil { return err } - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(0)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(0)) if err != nil { return err } @@ -697,7 +576,7 @@ func (p *Plural) handleKickClusterService(c *cli.Context) error { } func (p *Plural) handleTarballClusterService(c *cli.Context) error { - serviceId, clusterName, serviceName, err := getServiceIdClusterNameServiceName(c.Args().Get(0)) + serviceId, clusterName, serviceName, err := parseServiceIdentifier(c.Args().Get(0)) if err != nil { return fmt.Errorf("could not parse args: %w", err) } @@ -744,30 +623,55 @@ type ServiceDeploymentAttributesConfiguration struct { Configuration []*gqlclient.ConfigAttributes } -func getServiceIdClusterNameServiceName(input string) (serviceId, clusterName, serviceName *string, err error) { - if strings.HasPrefix(input, "@") { - i := strings.Trim(input, "@") +func validateFlag(ctx *cli.Context, name string, defaultVal string) (string, error) { + res := ctx.String(name) + if res == "" { + if defaultVal == "" { + return "", fmt.Errorf("expected --%s flag", name) + } + res = defaultVal + } + + return res, nil +} + +// parseServiceIdentifier parses the given identifier and returns the service id, cluster name, and service name. +// If the identifier is in the format @{cluster-handle}/{service-name}, the cluster name and service name are returned. +// Otherwise, the service id is returned. +func parseServiceIdentifier(id string) (serviceId, clusterName, serviceName *string, err error) { + if strings.HasPrefix(id, "@") { + i := strings.Trim(id, "@") split := strings.Split(i, "/") if len(split) != 2 { - err = fmt.Errorf("expected format @{cluster-handle}/{serviceName}") + err = fmt.Errorf("expected format @{cluster-handle}/{service-name} or {service-id}, got %s", id) return } clusterName = &split[0] serviceName = &split[1] } else { - serviceId = &input + serviceId = &id } + return } -func validateFlag(ctx *cli.Context, name string, defaultVal string) (string, error) { - res := ctx.String(name) - if res == "" { - if defaultVal == "" { - return "", fmt.Errorf("expected --%s flag", name) - } - res = defaultVal +// getService returns the service deployment for the given identifier. +// Identifier should be in the format of @{cluster-handle}/{service-name} or {service-id}. +// If the identifier is empty, it will return nil. +func getService(c console.ConsoleClient, id string) (*gqlclient.ServiceDeploymentExtended, error) { + if id == "" { + return nil, nil } - return res, nil + serviceId, clusterName, serviceName, err := parseServiceIdentifier(id) + if err != nil { + return nil, fmt.Errorf("could not parse identifier: %w", err) + } + + service, err := c.GetClusterService(serviceId, serviceName, clusterName) + if err != nil { + return nil, fmt.Errorf("could not get service deployment: %w", err) + } + + return service, lo.Ternary(service == nil, fmt.Errorf("could not find service deployment for %s", id), nil) } diff --git a/cmd/command/cd/cd_services_lua.go b/cmd/command/cd/cd_services_lua.go new file mode 100644 index 000000000..9c364ae68 --- /dev/null +++ b/cmd/command/cd/cd_services_lua.go @@ -0,0 +1,260 @@ +package cd + +import ( + "fmt" + iofs "io/fs" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/pluralsh/console/go/client" + "github.com/pluralsh/plural-cli/pkg/console" + + "github.com/pluralsh/plural-cli/pkg/utils" + "github.com/pluralsh/polly/luautils" + "github.com/samber/lo" + "github.com/urfave/cli" + lua "github.com/yuin/gopher-lua" +) + +func (p *Plural) handleLuaTemplate(c *cli.Context) error { + if err := p.InitConsoleClient(consoleToken, consoleURL); err != nil { + return err + } + + luaFile := c.String("lua-file") + if luaFile == "" { + return fmt.Errorf("expected --lua-file flag") + } + luaDir := c.String("lua-dir") + + context := c.String("context") + serviceIdentifier := c.String("service") + if !lo.IsEmpty(context) && !lo.IsEmpty(serviceIdentifier) { + return fmt.Errorf("cannot specify both --context and --service flags") + } + + dir := c.String("dir") + if dir == "" { + dir = "." + } + + luaStr, err := utils.ReadFile(luaFile) + if err != nil { + return err + } + + if luaDir != "" { + luaFiles, err := luaFolder(luaDir) + if err != nil { + return err + } + + luaStr = luaFiles + "\n\n" + luaStr + } + + dir, err = filepath.Abs(dir) + if err != nil { + return err + } + + bindings, err := luaBindings(p.ConsoleClient, context, serviceIdentifier) + if err != nil { + return err + } + + result, err := executeLuaTemplate(luaStr, dir, bindings) + if err != nil { + return err + } + + utils.Highlight("Final lua output:\n\n") + utils.NewYAMLPrinter(result).PrettyPrint() + return nil +} + +// executeLuaTemplate runs the given Lua script with the provided bindings and working directory, +// and returns a map with "values" and "valuesFiles" keys. +func executeLuaTemplate(luaStr, dir string, bindings map[string]interface{}) (map[string]interface{}, error) { + values := map[interface{}]interface{}{} + valuesFiles := []string{} + + L := luautils.NewLuaState(dir) + defer L.Close() + + // Register global values and valuesFiles in Lua + valuesTable := L.NewTable() + L.SetGlobal("values", valuesTable) + + valuesFilesTable := L.NewTable() + L.SetGlobal("valuesFiles", valuesFilesTable) + + for name, binding := range bindings { + L.SetGlobal(name, luautils.GoValueToLuaValue(L, binding)) + } + + if err := L.DoString(luaStr); err != nil { + return nil, err + } + + if err := luautils.MapLua(L.GetGlobal("values").(*lua.LTable), &values); err != nil { + return nil, err + } + + if err := luautils.MapLua(L.GetGlobal("valuesFiles").(*lua.LTable), &valuesFiles); err != nil { + return nil, err + } + + return map[string]interface{}{ + "values": luautils.SanitizeValue(values), + "valuesFiles": valuesFiles, + }, nil +} + +func luaFolder(folder string) (string, error) { + luaFiles := make([]string, 0) + if err := filepath.WalkDir(folder, func(path string, info iofs.DirEntry, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + + if strings.HasSuffix(info.Name(), ".lua") { + luaPath, err := filepath.Rel(folder, path) + if err != nil { + return err + } + luaFiles = append(luaFiles, luaPath) + } + + return nil + }); err != nil { + return "", fmt.Errorf("failed to walk lua folder %s: %w", folder, err) + } + + sort.Slice(luaFiles, func(i, j int) bool { + return luaFiles[i] < luaFiles[j] + }) + + luaFileContents := make([]string, 0) + for _, file := range luaFiles { + luaContents, err := os.ReadFile(file) + if err != nil { + return "", fmt.Errorf("failed to read lua file %s: %w", file, err) + } + luaFileContents = append(luaFileContents, string(luaContents)) + } + + return strings.Join(luaFileContents, "\n\n"), nil +} + +func luaBindings(client console.ConsoleClient, contextPath, serviceIdentifier string) (context map[string]interface{}, err error) { + if serviceIdentifier != "" { + service, err := getService(client, serviceIdentifier) + if err != nil { + return nil, err + } + + return map[string]interface{}{ + "configuration": luaConfigurationBinding(service), + "cluster": luaClusterBinding(service.Cluster), + "contexts": luaContextsBinding(service), + "imports": luaImportsBinding(service), + "service": luaServiceBinding(service), + }, nil + } + + if contextPath != "" { + err = utils.YamlFile(contextPath, &context) + return + } + + return +} + +func luaConfigurationBinding(svc *client.ServiceDeploymentExtended) map[string]string { + res := map[string]string{} + for _, config := range svc.Configuration { + res[config.Name] = config.Value + } + return res +} + +func luaClusterBinding(cluster *client.BaseClusterFragment) map[string]interface{} { + res := map[string]interface{}{ + "ID": cluster.ID, + "Self": cluster.Self, + "Handle": cluster.Handle, + "Name": cluster.Name, + "Version": cluster.Version, + "CurrentVersion": cluster.CurrentVersion, + "KasUrl": cluster.KasURL, + "Tags": luaClusterTagsBinding(cluster.Tags), + "Metadata": cluster.Metadata, + "Distro": cluster.Distro, + // "ConsoleDNS": args.ConsoleDNS(), + } + for k, v := range res { + res[strings.ToLower(k)] = v + } + res["kasUrl"] = cluster.KasURL + res["currentVersion"] = cluster.CurrentVersion + return res +} + +func luaClusterTagsBinding(tags []*client.ClusterTags) map[string]string { + res := map[string]string{} + for _, tag := range tags { + res[tag.Name] = tag.Value + } + return res +} + +func luaContextsBinding(svc *client.ServiceDeploymentExtended) map[string]map[string]interface{} { + res := map[string]map[string]interface{}{} + for _, context := range svc.Contexts { + res[context.Name] = context.Configuration + } + return res +} + +func luaImportsBinding(svc *client.ServiceDeploymentExtended) map[string]map[string]string { + res := map[string]map[string]string{} + for _, imp := range svc.Imports { + res[imp.Stack.Name] = map[string]string{} + for _, out := range imp.Outputs { + res[imp.Stack.Name][out.Name] = out.Value + } + } + return res +} + +func luaServiceBinding(svc *client.ServiceDeploymentExtended) map[string]interface{} { + res := map[string]interface{}{ + "Name": svc.Name, + "Namespace": svc.Namespace, + } + for k, v := range res { + res[strings.ToLower(k)] = v + } + // if svc.Helm != nil { + // helm := map[string]interface{}{ + // "Values": svc.Helm.Values, + // "ValuesFiles": svc.Helm.ValuesFiles, + // "LuaScript": svc.Helm.LuaScript, + // "LuaFile": svc.Helm.LuaFile, + // "LuaFolder": svc.Helm.LuaFolder, + // "KustomizePostrender": svc.Helm.KustomizePostrender, + // } + // + // for k, f := range helm { + // helm[strings.ToLower(k)] = f + // } + // res["helm"] = helm + // res["Helm"] = helm + //} + return res +} diff --git a/cmd/command/cd/cd_services_lua_test.go b/cmd/command/cd/cd_services_lua_test.go new file mode 100644 index 000000000..cceb00b35 --- /dev/null +++ b/cmd/command/cd/cd_services_lua_test.go @@ -0,0 +1,443 @@ +package cd + +import ( + "errors" + "os" + "path/filepath" + "testing" + + client "github.com/pluralsh/console/go/client" + "github.com/pluralsh/plural-cli/pkg/test/mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestExecuteLuaTemplate_EmptyScript(t *testing.T) { + dir := t.TempDir() + + result, err := executeLuaTemplate("", dir, nil) + + require.NoError(t, err) + assert.Empty(t, result["valuesFiles"]) +} + +func TestExecuteLuaTemplate_SetsValues(t *testing.T) { + dir := t.TempDir() + script := ` +values["replicas"] = 3 +values["image"] = "nginx" +` + result, err := executeLuaTemplate(script, dir, nil) + + require.NoError(t, err) + values, ok := result["values"].(map[string]any) + require.True(t, ok, "values should be map[string]any") + assert.Equal(t, float64(3), values["replicas"]) + assert.Equal(t, "nginx", values["image"]) + assert.Empty(t, result["valuesFiles"]) +} + +func TestExecuteLuaTemplate_SetsValuesFiles(t *testing.T) { + dir := t.TempDir() + script := ` +valuesFiles[1] = "base.yaml" +valuesFiles[2] = "override.yaml" +` + result, err := executeLuaTemplate(script, dir, nil) + + require.NoError(t, err) + valuesFiles, ok := result["valuesFiles"].([]string) + require.True(t, ok, "valuesFiles should be []string") + assert.Equal(t, []string{"base.yaml", "override.yaml"}, valuesFiles) +} + +func TestExecuteLuaTemplate_SyntaxError(t *testing.T) { + dir := t.TempDir() + script := `this is not valid lua %%%` + + _, err := executeLuaTemplate(script, dir, nil) + + assert.Error(t, err) +} + +func TestExecuteLuaTemplate_RuntimeError(t *testing.T) { + dir := t.TempDir() + script := ` +local x = nil +x.field = "boom" +` + _, err := executeLuaTemplate(script, dir, nil) + + assert.Error(t, err) +} + +func TestExecuteLuaTemplate_NestedValues(t *testing.T) { + dir := t.TempDir() + script := ` +values["db"] = { host = "localhost", port = 5432 } +` + result, err := executeLuaTemplate(script, dir, nil) + + require.NoError(t, err) + values, ok := result["values"].(map[string]any) + require.True(t, ok) + db, ok := values["db"].(map[string]any) + require.True(t, ok, "db should be a nested map") + assert.Equal(t, "localhost", db["host"]) + assert.Equal(t, float64(5432), db["port"]) +} + +func TestExecuteLuaTemplate_UsesTempDir(t *testing.T) { + dir := t.TempDir() + helperContent := ` +function greet(name) + return "hello " .. name +end +` + helperPath := filepath.Join(dir, "helper.lua") + err := os.WriteFile(helperPath, []byte(helperContent), 0600) + require.NoError(t, err) + + // Use dofile with absolute path; require resolves relative to CWD, not dir. + script := "dofile('" + helperPath + "')\n" + ` +values["greeting"] = greet("world") +` + result, err := executeLuaTemplate(script, dir, nil) + + require.NoError(t, err) + values, ok := result["values"].(map[string]any) + require.True(t, ok) + assert.Equal(t, "hello world", values["greeting"]) +} + +// Binding tests – each test mirrors what the real luaBindings helpers produce, +// then asserts that Lua can read those values as expected. + +func TestExecuteLuaTemplate_ConfigurationBinding(t *testing.T) { + dir := t.TempDir() + // Mirrors luaConfigurationBinding: map[string]string keyed by config name. + script := ` +values["env"] = configuration["env"] +values["region"] = configuration["region"] +` + bindings := map[string]any{ + "configuration": map[string]string{ + "env": "production", + "region": "us-east-1", + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "production", values["env"]) + assert.Equal(t, "us-east-1", values["region"]) +} + +func TestExecuteLuaTemplate_ServiceBinding(t *testing.T) { + dir := t.TempDir() + // Mirrors luaServiceBinding: both PascalCase and lowercase keys are present. + script := ` +values["name"] = service["name"] +values["namespace"] = service["namespace"] +values["Name"] = service["Name"] +` + bindings := map[string]any{ + "service": map[string]any{ + "name": "my-service", + "Name": "my-service", + "namespace": "default", + "Namespace": "default", + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "my-service", values["name"]) + assert.Equal(t, "default", values["namespace"]) + assert.Equal(t, "my-service", values["Name"]) +} + +func TestExecuteLuaTemplate_ClusterBinding(t *testing.T) { + dir := t.TempDir() + // Mirrors luaClusterBinding: both PascalCase and lowercase keys, plus tags sub-map. + script := ` +values["clusterName"] = cluster["name"] +values["clusterHandle"] = cluster["handle"] +values["tagEnv"] = cluster["tags"]["env"] +` + bindings := map[string]any{ + "cluster": map[string]any{ + "name": "prod-cluster", + "Name": "prod-cluster", + "handle": "prod", + "Handle": "prod", + "tags": map[string]string{ + "env": "production", + }, + "Tags": map[string]string{ + "env": "production", + }, + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "prod-cluster", values["clusterName"]) + assert.Equal(t, "prod", values["clusterHandle"]) + assert.Equal(t, "production", values["tagEnv"]) +} + +func TestExecuteLuaTemplate_ContextsBinding(t *testing.T) { + dir := t.TempDir() + // Mirrors luaContextsBinding: map[contextName]map[string]any. + script := ` +values["dbHost"] = contexts["db-context"]["host"] +values["dbPort"] = contexts["db-context"]["port"] +` + bindings := map[string]any{ + "contexts": map[string]map[string]any{ + "db-context": { + "host": "db.internal", + "port": 5432, + }, + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "db.internal", values["dbHost"]) + assert.Equal(t, float64(5432), values["dbPort"]) +} + +func TestExecuteLuaTemplate_ImportsBinding(t *testing.T) { + dir := t.TempDir() + // Mirrors luaImportsBinding: map[stackName]map[outputName]string. + script := ` +values["vpcId"] = imports["network-stack"]["vpc_id"] +values["subnetId"] = imports["network-stack"]["subnet_id"] +` + bindings := map[string]any{ + "imports": map[string]map[string]string{ + "network-stack": { + "vpc_id": "vpc-abc123", + "subnet_id": "subnet-def456", + }, + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "vpc-abc123", values["vpcId"]) + assert.Equal(t, "subnet-def456", values["subnetId"]) +} + +func TestExecuteLuaTemplate_MultipleBindingsUsedTogether(t *testing.T) { + dir := t.TempDir() + // Verifies that all binding types are available in a single script execution. + script := ` +values["svcName"] = service["name"] +values["cfgEnv"] = configuration["env"] +values["cluster"] = cluster["name"] +values["ctxHost"] = contexts["infra"]["endpoint"] +values["importOut"] = imports["infra-stack"]["bucket"] +` + bindings := map[string]any{ + "service": map[string]any{"name": "api", "Name": "api"}, + "configuration": map[string]string{"env": "staging"}, + "cluster": map[string]any{"name": "staging-cluster", "Name": "staging-cluster"}, + "contexts": map[string]map[string]any{ + "infra": {"endpoint": "https://infra.internal"}, + }, + "imports": map[string]map[string]string{ + "infra-stack": {"bucket": "my-bucket"}, + }, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "api", values["svcName"]) + assert.Equal(t, "staging", values["cfgEnv"]) + assert.Equal(t, "staging-cluster", values["cluster"]) + assert.Equal(t, "https://infra.internal", values["ctxHost"]) + assert.Equal(t, "my-bucket", values["importOut"]) +} + +func TestExecuteLuaTemplate_MissingBindingKeyIsNil(t *testing.T) { + dir := t.TempDir() + // Accessing a missing key in a binding map returns nil in Lua, not an error. + script := ` +if configuration["missing"] == nil then + values["result"] = "nil as expected" +end +` + bindings := map[string]any{ + "configuration": map[string]string{"existing": "value"}, + } + + result, err := executeLuaTemplate(script, dir, bindings) + + require.NoError(t, err) + values := result["values"].(map[string]any) + assert.Equal(t, "nil as expected", values["result"]) +} + +func TestLuaBindings_WithServiceIdentifier(t *testing.T) { + clusterHandle := "prod" + clusterSelf := true + clusterVersion := "1.30.1" + clusterCurrentVersion := "1.30.2" + clusterKasURL := "wss://kas.example.com" + stackID := "stack-1" + + service := &client.ServiceDeploymentExtended{ + Name: "payments", + Namespace: "apps", + Configuration: []*client.ServiceDeploymentExtended_Configuration{ + {Name: "env", Value: "production"}, + {Name: "region", Value: "us-east-1"}, + }, + Cluster: &client.BaseClusterFragment{ + ID: "cluster-1", + Name: "production", + Handle: &clusterHandle, + Self: &clusterSelf, + Version: &clusterVersion, + CurrentVersion: &clusterCurrentVersion, + KasURL: &clusterKasURL, + Metadata: map[string]any{"team": "platform"}, + Tags: []*client.ClusterTags{ + {Name: "env", Value: "prod"}, + }, + }, + Contexts: []*client.ServiceContextFragment{ + { + Name: "db", + Configuration: map[string]any{"host": "db.internal", "port": 5432}, + }, + }, + Imports: []*client.ServiceDeploymentExtended_Imports{ + { + Stack: &client.InfrastructureStackTinyFragment{ + ID: &stackID, + Name: "network", + }, + Outputs: []*client.StackOutputFragment{ + {Name: "vpc_id", Value: "vpc-123"}, + }, + }, + }, + } + + consoleClient := mocks.NewConsoleClient(t) + consoleClient. + On( + "GetClusterService", + mock.MatchedBy(func(serviceID *string) bool { return serviceID != nil && *serviceID == "svc-123" }), + mock.MatchedBy(func(serviceName *string) bool { return serviceName == nil }), + mock.MatchedBy(func(clusterName *string) bool { return clusterName == nil }), + ). + Return(service, nil). + Once() + + bindings, err := luaBindings(consoleClient, "", "svc-123") + + require.NoError(t, err) + require.NotNil(t, bindings) + assert.Equal(t, map[string]string{ + "env": "production", + "region": "us-east-1", + }, bindings["configuration"]) + clusterBindings, ok := bindings["cluster"].(map[string]interface{}) + require.True(t, ok) + assert.Equal(t, "cluster-1", clusterBindings["ID"]) + assert.Equal(t, "cluster-1", clusterBindings["id"]) + assert.Equal(t, &clusterHandle, clusterBindings["Handle"]) + assert.Equal(t, &clusterHandle, clusterBindings["handle"]) + assert.Equal(t, "production", clusterBindings["Name"]) + assert.Equal(t, "production", clusterBindings["name"]) + assert.Equal(t, &clusterVersion, clusterBindings["Version"]) + assert.Equal(t, &clusterVersion, clusterBindings["version"]) + assert.Equal(t, &clusterCurrentVersion, clusterBindings["CurrentVersion"]) + assert.Equal(t, &clusterCurrentVersion, clusterBindings["currentVersion"]) + assert.Equal(t, &clusterCurrentVersion, clusterBindings["currentversion"]) + assert.Equal(t, &clusterKasURL, clusterBindings["KasUrl"]) + assert.Equal(t, &clusterKasURL, clusterBindings["kasUrl"]) + assert.Equal(t, &clusterKasURL, clusterBindings["kasurl"]) + assert.Equal(t, &clusterSelf, clusterBindings["Self"]) + assert.Equal(t, &clusterSelf, clusterBindings["self"]) + assert.Equal(t, map[string]string{"env": "prod"}, clusterBindings["Tags"]) + assert.Equal(t, map[string]string{"env": "prod"}, clusterBindings["tags"]) + assert.Equal(t, map[string]any{"team": "platform"}, clusterBindings["Metadata"]) + assert.Equal(t, map[string]any{"team": "platform"}, clusterBindings["metadata"]) + assert.Nil(t, clusterBindings["Distro"]) + assert.Nil(t, clusterBindings["distro"]) + assert.Equal(t, map[string]map[string]interface{}{ + "db": { + "host": "db.internal", + "port": 5432, + }, + }, bindings["contexts"]) + assert.Equal(t, map[string]map[string]string{ + "network": { + "vpc_id": "vpc-123", + }, + }, bindings["imports"]) + assert.Equal(t, map[string]interface{}{ + "Name": "payments", + "name": "payments", + "Namespace": "apps", + "namespace": "apps", + }, bindings["service"]) + consoleClient.AssertExpectations(t) +} + +func TestLuaBindings_WithContextPath(t *testing.T) { + contextPath := filepath.Join(t.TempDir(), "context.yaml") + err := os.WriteFile(contextPath, []byte("foo: bar\nnested:\n port: 5432\n"), 0o600) + require.NoError(t, err) + + bindings, err := luaBindings(nil, contextPath, "") + + require.NoError(t, err) + assert.Equal(t, map[string]interface{}{ + "foo": "bar", + "nested": map[string]interface{}{ + "port": float64(5432), + }, + }, bindings) +} + +func TestLuaBindings_ServiceIdentifierError(t *testing.T) { + expectedErr := errors.New("boom") + consoleClient := mocks.NewConsoleClient(t) + consoleClient. + On( + "GetClusterService", + mock.MatchedBy(func(serviceID *string) bool { return serviceID == nil }), + mock.MatchedBy(func(serviceName *string) bool { return serviceName != nil && *serviceName == "payments" }), + mock.MatchedBy(func(clusterName *string) bool { return clusterName != nil && *clusterName == "prod" }), + ). + Return((*client.ServiceDeploymentExtended)(nil), expectedErr). + Once() + + bindings, err := luaBindings(consoleClient, "", "@prod/payments") + + require.Error(t, err) + assert.Nil(t, bindings) + assert.ErrorContains(t, err, "could not get service deployment") + assert.ErrorIs(t, err, expectedErr) + consoleClient.AssertExpectations(t) +} diff --git a/cmd/command/plural/plural.go b/cmd/command/plural/plural.go index ac2a5816c..c201ee668 100644 --- a/cmd/command/plural/plural.go +++ b/cmd/command/plural/plural.go @@ -102,7 +102,8 @@ func CreateNewApp(plural *Plural) *cli.App { app.Usage = "Tooling to manage your installed plural applications" app.EnableBashCompletion = true app.Flags = globalFlags() - commands := []cli.Command{ + commands := make([]cli.Command, 0, 15+len(plural.getCommands())) + commands = append(commands, api.Command(plural.Plural), auth.Command(plural.Plural), cd.Command(plural.Plural, plural.HelmConfiguration), @@ -118,7 +119,7 @@ func CreateNewApp(plural *Plural) *cli.App { cmdinit.Command(plural.Plural), up.Command(plural.Plural), version.Command(), - } + ) commands = append(commands, plural.getCommands()...) app.Commands = commands diff --git a/go.mod b/go.mod index 82c72e461..47518a2b8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/pluralsh/plural-cli -go 1.25.8 +go 1.26.1 require ( cloud.google.com/go/compute v1.54.0 @@ -41,11 +41,12 @@ require ( github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c - github.com/pluralsh/console/go/client v1.61.0 + github.com/pluralsh/console/go/client v1.70.0 github.com/pluralsh/console/go/controller v0.0.0-20260129150042-18e31f596bd7 github.com/pluralsh/console/go/polly v1.0.0 github.com/pluralsh/gqlclient v1.12.2 github.com/pluralsh/plural-operator v0.5.5 + github.com/pluralsh/polly v0.3.6 github.com/posthog/posthog-go v1.4.10 github.com/samber/lo v1.52.0 github.com/urfave/cli v1.22.16 @@ -80,21 +81,21 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect - github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/obfuscate v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/proto v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.69.0 // indirect - github.com/DataDog/datadog-agent/pkg/trace v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/util/log v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/util/scrubber v0.67.0 // indirect - github.com/DataDog/datadog-agent/pkg/version v0.67.0 // indirect + github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/obfuscate v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/proto v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.73.0-rc.1 // indirect + github.com/DataDog/datadog-agent/pkg/trace v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/util/log v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/util/scrubber v0.71.0 // indirect + github.com/DataDog/datadog-agent/pkg/version v0.71.0 // indirect github.com/DataDog/datadog-go/v5 v5.6.0 // indirect - github.com/DataDog/dd-trace-go/v2 v2.3.0 // indirect - github.com/DataDog/go-libddwaf/v4 v4.3.2 // indirect + github.com/DataDog/dd-trace-go/v2 v2.5.0 // indirect + github.com/DataDog/go-libddwaf/v4 v4.8.0 // indirect github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 // indirect - github.com/DataDog/go-sqllexer v0.1.6 // indirect - github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect - github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.27.0 // indirect + github.com/DataDog/go-sqllexer v0.1.8 // indirect + github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect github.com/DataDog/sketches-go v1.4.7 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect @@ -129,7 +130,7 @@ require ( github.com/docker/docker-credential-helpers v0.9.5 // indirect github.com/docker/go-events v0.0.0-20250808211157-605354379745 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/ebitengine/purego v0.8.4 // indirect + github.com/ebitengine/purego v0.9.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect @@ -154,8 +155,6 @@ require ( github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-openapi/testify/enable/yaml/v2 v2.3.0 // indirect github.com/go-openapi/testify/v2 v2.3.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.7.1 // indirect @@ -169,17 +168,17 @@ require ( github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/likexian/gokit v0.25.15 // indirect - github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect + github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect + github.com/minio/simdjson-go v0.4.5 // indirect github.com/mitchellh/pointerstructure v1.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/osteele/liquid v1.8.1 // indirect github.com/osteele/tuesday v1.0.4 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect - github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect + github.com/philhofer/fwd v1.2.0 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pluralsh/controller-reconcile-helper v0.1.0 // indirect - github.com/pluralsh/polly v0.3.6 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect @@ -188,13 +187,13 @@ require ( github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect - github.com/shirou/gopsutil/v4 v4.25.7 // indirect + github.com/shirou/gopsutil/v4 v4.25.10 // indirect github.com/skeema/knownhosts v1.3.2 // indirect github.com/sosodev/duration v1.3.1 // indirect github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/theckman/httpforwarded v0.4.0 // indirect - github.com/tinylib/msgp v1.2.5 // indirect + github.com/tinylib/msgp v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/vbatts/tar-split v0.12.1 // indirect @@ -202,17 +201,17 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component v1.31.0 // indirect - go.opentelemetry.io/collector/featuregate v1.31.0 // indirect - go.opentelemetry.io/collector/internal/telemetry v0.125.0 // indirect - go.opentelemetry.io/collector/pdata v1.31.0 // indirect - go.opentelemetry.io/collector/semconv v0.125.0 // indirect - go.opentelemetry.io/contrib/bridges/otelzap v0.10.0 // indirect + go.opentelemetry.io/collector/component v1.39.0 // indirect + go.opentelemetry.io/collector/featuregate v1.46.0 // indirect + go.opentelemetry.io/collector/internal/telemetry v0.133.0 // indirect + go.opentelemetry.io/collector/pdata v1.46.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.140.0 // indirect + go.opentelemetry.io/contrib/bridges/otelzap v0.12.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/log v0.11.0 // indirect + go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect diff --git a/go.sum b/go.sum index e776bc1b9..d0e26d82f 100644 --- a/go.sum +++ b/go.sum @@ -102,38 +102,38 @@ github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.67.0 h1:2mEwRWvhIPHMPK4CMD8iKbsrYBxeMBSuuCXumQAwShU= -github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.67.0/go.mod h1:ejJHsyJTG7NU6c6TDbF7dmckD3g+AUGSdiSXy+ZyaCE= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.67.0 h1:NcvyDVIUA0NbBDbp7QJnsYhoBv548g8bXq886795mCQ= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.67.0/go.mod h1:1oPcs3BUTQhiTkmk789rb7ob105MxNV6OuBa28BdukQ= -github.com/DataDog/datadog-agent/pkg/proto v0.67.0 h1:7dO6mKYRb7qSiXEu7Q2mfeKbhp4hykCAULy4BfMPmsQ= -github.com/DataDog/datadog-agent/pkg/proto v0.67.0/go.mod h1:bKVXB7pxBg0wqXF6YSJ+KU6PeCWKDyJj83kUH1ab+7o= -github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.69.0 h1:/DsN4R+IkC6t1+4cHSfkxzLtDl84rBbPC5Wa9srBAoM= -github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.69.0/go.mod h1:Th2LD/IGid5Rza55pzqGu6nUdOv/Rts6wPwLjTyOSTs= -github.com/DataDog/datadog-agent/pkg/trace v0.67.0 h1:dqt+/nObo0JKyaEqIMZgfqGZbx9TfEHpCkrjQ/zzH7k= -github.com/DataDog/datadog-agent/pkg/trace v0.67.0/go.mod h1:zmZoEtKvOnaKHbJGBKH3a4xuyPrSfBaF0ZE3Q3rCoDw= -github.com/DataDog/datadog-agent/pkg/util/log v0.67.0 h1:xrH15QNqeJZkYoXYi44VCIvGvTwlQ3z2iT2QVTGiT7s= -github.com/DataDog/datadog-agent/pkg/util/log v0.67.0/go.mod h1:dfVLR+euzEyg1CeiExgJQq1c1dod42S6IeiRPj8H7Yk= -github.com/DataDog/datadog-agent/pkg/util/scrubber v0.67.0 h1:aIWF85OKxXGo7rVyqJ7jm7lm2qCQrgyXzYyFuw0T2EQ= -github.com/DataDog/datadog-agent/pkg/util/scrubber v0.67.0/go.mod h1:Lfap5FuM4b/Pw9IrTuAvWBWZEmXOvZhCya3dYv4G8O0= -github.com/DataDog/datadog-agent/pkg/version v0.67.0 h1:TB8H8r+laB1Qdttvvc6XJVyLGxp8E6j2f2Mh5IPbYmQ= -github.com/DataDog/datadog-agent/pkg/version v0.67.0/go.mod h1:kvAw/WbI7qLAsDI2wHabZfM7Cv2zraD3JA3323GEB+8= +github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.71.0 h1:xjmjXOsiLfUF1wWXYXc8Gg6M7Jbz6a7FtqbnvGKfTvA= +github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.71.0/go.mod h1:y05SPqKEtrigKul+JBVM69ehv3lOgyKwrUIwLugoaSI= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.71.0 h1:jX8qS7CkNzL1fdcDptrOkbWpsRFTQ58ICjp/mj02u1k= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.71.0/go.mod h1:B3T0If+WdWAwPMpawjm1lieJyqSI0v04dQZHq15WGxY= +github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.71.0 h1:bowQteds9+7I4Dd+CsBRVXdlMOOGuBm5zdUQdB/6j1M= +github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.71.0/go.mod h1:XeZj0IgsiL3vgeEGTucf61JvJRh1LxWMUbZA/XJsPD0= +github.com/DataDog/datadog-agent/pkg/proto v0.71.0 h1:YTwecwy8kF1zsL2HK6KVa7XLRZYZ0Ypb2anlG0zDLeE= +github.com/DataDog/datadog-agent/pkg/proto v0.71.0/go.mod h1:KSn4jt3CykV6CT1C8Rknn/Nj3E+VYHK/UDWolg/+kzw= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.73.0-rc.1 h1:fVqr9ApWmUMEExmgn8iFPfwm9ZrlEfFWgTKp1IcNH18= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.73.0-rc.1/go.mod h1:lwkSvCXABHXyqy6mG9WBU6MTK9/E0i0R8JVApUtT+XA= +github.com/DataDog/datadog-agent/pkg/trace v0.71.0 h1:9UrKHDacMlAWfP2wpSxrZOQbtkwLY2AOAjYgGkgM96Y= +github.com/DataDog/datadog-agent/pkg/trace v0.71.0/go.mod h1:wfVwOlKORIB4IB1vdncTuCTx/OrVU69TLBIiBpewe1Q= +github.com/DataDog/datadog-agent/pkg/util/log v0.71.0 h1:VJ+nm5E0+UdLPkg2H7FKapx0syNcKzCFXA2vfcHz0Bc= +github.com/DataDog/datadog-agent/pkg/util/log v0.71.0/go.mod h1:oG6f6Qe23zPTLOVh0nXjlIXohrjUGXeFjh7S3Na/WyU= +github.com/DataDog/datadog-agent/pkg/util/scrubber v0.71.0 h1:lA3CL+2yHU9gulyR/C0VssVzmvCs/jCHzt+CBs9uH4Q= +github.com/DataDog/datadog-agent/pkg/util/scrubber v0.71.0/go.mod h1:/JHi9UFqdFYy/SFmFozY26dNOl/ODVLSQaF1LKDPiBI= +github.com/DataDog/datadog-agent/pkg/version v0.71.0 h1:jqkKmhFrhHSLpiC3twQFDCXU7nyFcC1EnwagDQxFWVs= +github.com/DataDog/datadog-agent/pkg/version v0.71.0/go.mod h1:FYj51C1ib86rpr5tlLEep9jitqvljIJ5Uz2rrimGTeY= github.com/DataDog/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= -github.com/DataDog/dd-trace-go/v2 v2.3.0 h1:0Y5kx+Wbod0z8moY0vUbKl6OM0oIV4zAynsVmsq+XT8= -github.com/DataDog/dd-trace-go/v2 v2.3.0/go.mod h1:yFomJ/rqKNLDbS9ohIDibdz8q9GK0MUSSkBdVDCibGA= -github.com/DataDog/go-libddwaf/v4 v4.3.2 h1:YGvW2Of1C4e1yU+p7iibmhN2zEOgi9XEchbhQjBxb/A= -github.com/DataDog/go-libddwaf/v4 v4.3.2/go.mod h1:/AZqP6zw3qGJK5mLrA0PkfK3UQDk1zCI2fUNCt4xftE= +github.com/DataDog/dd-trace-go/v2 v2.5.0 h1:Tp4McT135WhbdT/6BYcAoRvl5gH7YKzehSo6Q3uuxBM= +github.com/DataDog/dd-trace-go/v2 v2.5.0/go.mod h1:A9rVmQfyzYUFCctFdKkli9us7G/YhXlMICpQ958wJUA= +github.com/DataDog/go-libddwaf/v4 v4.8.0 h1:m6Bl1lS2RtVN4MtdTYhR5vJ2fWQ3WmNy4FiNBpzrp6w= +github.com/DataDog/go-libddwaf/v4 v4.8.0/go.mod h1:/AZqP6zw3qGJK5mLrA0PkfK3UQDk1zCI2fUNCt4xftE= github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 h1:ZRLR9Lbym748e8RznWzmSoK+OfV+8qW6SdNYA4/IqdA= github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633/go.mod h1:YFoTl1xsMzdSRFIu33oCSPS/3+HZAPGpO3oOM96wXCM= -github.com/DataDog/go-sqllexer v0.1.6 h1:skEXpWEVCpeZFIiydoIa2f2rf+ymNpjiIMqpW4w3YAk= -github.com/DataDog/go-sqllexer v0.1.6/go.mod h1:GGpo1h9/BVSN+6NJKaEcJ9Jn44Hqc63Rakeb+24Mjgo= -github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= -github.com/DataDog/go-tuf v1.1.0-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= +github.com/DataDog/go-sqllexer v0.1.8 h1:ku9DpghFHeyyviR28W/3R4cCJwzpsuC08YIoltnx5ds= +github.com/DataDog/go-sqllexer v0.1.8/go.mod h1:GGpo1h9/BVSN+6NJKaEcJ9Jn44Hqc63Rakeb+24Mjgo= +github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJxPknv0= +github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= -github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.27.0 h1:5US5SqqhfkZkg/E64uvn7YmeTwnudJHtlPEH/LOT99w= -github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.27.0/go.mod h1:VRo4D6rj92AExpVBlq3Gcuol9Nm1bber12KyxRjKGWw= github.com/DataDog/sketches-go v1.4.7 h1:eHs5/0i2Sdf20Zkj0udVFWuCrXGRFig2Dcfm5rtcTxc= github.com/DataDog/sketches-go v1.4.7/go.mod h1:eAmQ/EBmtSO+nQp7IZMZVRPT4BQTmIc5RZQ+deGlTPM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= @@ -299,8 +299,8 @@ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHz github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= -github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= +github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= @@ -400,14 +400,10 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -440,8 +436,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/pprof v0.0.0-20251213031049-b05bdaca462f h1:HU1RgM6NALf/KW9HEY6zry3ADbDKcmpQ+hJedoNGQYQ= -github.com/google/pprof v0.0.0-20251213031049-b05bdaca462f/go.mod h1:67FPmZWbr+KDT/VlpWtw6sO9XSjpJmLuHpoLmWiTGgY= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= +github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -500,8 +496,6 @@ github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRg github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= @@ -531,8 +525,8 @@ github.com/likexian/doh v0.7.1 h1:0p75orMxXrfGNAOnOEtl2xZ5T9Ctqi++i/WhN6P6hs8= github.com/likexian/doh v0.7.1/go.mod h1:aIEOK197o6nC82iRo5+5L5ws+X7xRCmuer3M4In91WA= github.com/likexian/gokit v0.25.15 h1:QjospM1eXhdMMHwZRpMKKAHY/Wig9wgcREmLtf9NslY= github.com/likexian/gokit v0.25.15/go.mod h1:S2QisdsxLEHWeD/XI0QMVeggp+jbxYqUxMvSBil7MRg= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= -github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= +github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc= +github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -556,6 +550,8 @@ github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a/go.mod h1:v8eSC2SMp9/7FTKUncp7fH9IwPfw+ysMObcEz5FWheQ= +github.com/minio/simdjson-go v0.4.5 h1:r4IQwjRGmWCQ2VeMc7fGiilu1z5du0gJ/I/FsKwgo5A= +github.com/minio/simdjson-go v0.4.5/go.mod h1:eoNz0DcLQRyEDeaPr4Ru6JpjlZPzbA0IodxVJk8lO8E= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -593,10 +589,10 @@ github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.125.0 h1:0dOJCEtabevxxDQmxed69oMzSw+gb3ErCnFwFYZFu0M= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.125.0/go.mod h1:QwzQhtxPThXMUDW1XRXNQ+l0GrI2BRsvNhX6ZuKyAds= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.125.0 h1:F68/Nbpcvo3JZpaWlRUDJtG7xs8FHBZ7A8GOMauDkyc= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.125.0/go.mod h1:haO4cJtAk05Y0p7NO9ME660xxtSh54ifCIIT7+PO9C0= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.133.0 h1:iPei+89a2EK4LuN4HeIRzZNE6XxCyrKfBKG3BkK/ViU= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.133.0/go.mod h1:asV77TgnGfc7A+a9jggdsnlLlW5dnJT8RroVuf5slko= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.133.0 h1:4ca2pM3+xDMB9H3UnhjAiNg7EpIydZ7HdohOexU8xb8= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.133.0/go.mod h1:3N2Saf55l9vrxjbf3KCEcBjbLHDZtbN4nPcxREztpPU= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -611,8 +607,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= -github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -622,8 +618,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= -github.com/pluralsh/console/go/client v1.61.0 h1:gy5tglnBLoMA6iBgXoCxXJFGpTUvRWh8qKQroUF4XzQ= -github.com/pluralsh/console/go/client v1.61.0/go.mod h1:lqN15ajFf+0MtnNQNb9rvQpxkdsuMg47Yd9dSdQDIAk= +github.com/pluralsh/console/go/client v1.70.0 h1:/1ij0qmfZQTWsgASx+UkXiygwQcXMu0LHDOsTCYDB+A= +github.com/pluralsh/console/go/client v1.70.0/go.mod h1:iOwV7fDsfsMW74i+lFRePKQOsYaHl1FhjHVtHgzv8bY= github.com/pluralsh/console/go/controller v0.0.0-20260129150042-18e31f596bd7 h1:CwBTb7Tvt11nO/XJ1PA9fbCsJSlz9/nDN1OJU0Pddsg= github.com/pluralsh/console/go/controller v0.0.0-20260129150042-18e31f596bd7/go.mod h1:bbAQqSq+Rne2mBzUwAVAaGOcR75sJZhnHdpDmHLTq2U= github.com/pluralsh/console/go/polly v1.0.0 h1:NRg8CMITGllEJ08oYidNuuG/gJGDdDuga8TM+gdIcFA= @@ -686,8 +682,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3 github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/shirou/gopsutil/v4 v4.25.7 h1:bNb2JuqKuAu3tRlPv5piSmBZyMfecwQ+t/ILq+1JqVM= -github.com/shirou/gopsutil/v4 v4.25.7/go.mod h1:XV/egmwJtd3ZQjBpJVY5kndsiOO4IRqy9TQnmm6VP7U= +github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= +github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -728,8 +724,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/theckman/httpforwarded v0.4.0 h1:N55vGJT+6ojTnLY3LQCNliJC4TW0P0Pkeys1G1WpX2w= github.com/theckman/httpforwarded v0.4.0/go.mod h1:GVkFynv6FJreNbgH/bpOU9ITDZ7a5WuzdNCtIMI1pVI= -github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po= -github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= +github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww= +github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= @@ -757,8 +753,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= @@ -769,42 +763,40 @@ gitlab.com/gitlab-org/api/client-go v0.128.0 h1:Wvy1UIuluKemubao2k8EOqrl3gbgJ1PV gitlab.com/gitlab-org/api/client-go v0.128.0/go.mod h1:bYC6fPORKSmtuPRyD9Z2rtbAjE7UeNatu2VWHRf4/LE= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/collector/component v1.31.0 h1:9LzU8X1RhV3h8/QsAoTX23aFUfoJ3EUc9O/vK+hFpSI= -go.opentelemetry.io/collector/component v1.31.0/go.mod h1:JbZl/KywXJxpUXPbt96qlEXJSym1zQ2hauMxYMuvlxM= -go.opentelemetry.io/collector/component/componentstatus v0.125.0 h1:zlxGQZYd9kknRZSjRpOYW5SBjl0a5zYFYRPbreobXoU= -go.opentelemetry.io/collector/component/componentstatus v0.125.0/go.mod h1:bHXc2W8bqqo9adOvCgvhcO7pYzJOSpyV4cuQ1wiIl04= -go.opentelemetry.io/collector/component/componenttest v0.125.0 h1:E2mpnMQbkMpYoZ3Q8pHx4kod7kedjwRs1xqDpzCe/84= -go.opentelemetry.io/collector/component/componenttest v0.125.0/go.mod h1:pQtsE1u/SPZdTphP5BZP64XbjXSq6wc+mDut5Ws/JDI= -go.opentelemetry.io/collector/consumer v1.31.0 h1:L+y66ywxLHnAxnUxv0JDwUf5bFj53kMxCCyEfRKlM7s= -go.opentelemetry.io/collector/consumer v1.31.0/go.mod h1:rPsqy5ni+c6xNMUkOChleZYO/nInVY6eaBNZ1FmWJVk= -go.opentelemetry.io/collector/consumer/consumertest v0.125.0 h1:TUkxomGS4DAtjBvcWQd2UY4FDLLEKMQD6iOIDUr/5dM= -go.opentelemetry.io/collector/consumer/consumertest v0.125.0/go.mod h1:vkHf3y85cFLDHARO/cTREVjLjOPAV+cQg7lkC44DWOY= -go.opentelemetry.io/collector/consumer/xconsumer v0.125.0 h1:oTreUlk1KpMSWwuHFnstW+orrjGTyvs2xd3o/Dpy+hI= -go.opentelemetry.io/collector/consumer/xconsumer v0.125.0/go.mod h1:FX0G37r0W+wXRgxxFtwEJ4rlsCB+p0cIaxtU3C4hskw= -go.opentelemetry.io/collector/featuregate v1.31.0 h1:20q7plPQZwmAiaYAa6l1m/i2qDITZuWlhjr4EkmeQls= -go.opentelemetry.io/collector/featuregate v1.31.0/go.mod h1:Y/KsHbvREENKvvN9RlpiWk/IGBK+CATBYzIIpU7nccc= -go.opentelemetry.io/collector/internal/telemetry v0.125.0 h1:6lcGOxw3dAg7LfXTKdN8ZjR+l7KvzLdEiPMhhLwG4r4= -go.opentelemetry.io/collector/internal/telemetry v0.125.0/go.mod h1:5GyFslLqjZgq1DZTtFiluxYhhXrCofHgOOOybodDPGE= -go.opentelemetry.io/collector/pdata v1.31.0 h1:P5WuLr1l2JcIvr6Dw2hl01ltp2ZafPnC4Isv+BLTBqU= -go.opentelemetry.io/collector/pdata v1.31.0/go.mod h1:m41io9nWpy7aCm/uD1L9QcKiZwOP0ldj83JEA34dmlk= -go.opentelemetry.io/collector/pdata/pprofile v0.125.0 h1:Qqlx8w1HpiYZ9RQqjmMQIysI0cHNO1nh3E/fCTeFysA= -go.opentelemetry.io/collector/pdata/pprofile v0.125.0/go.mod h1:p/yK023VxAp8hm27/1G5DPTcMIpnJy3cHGAFUQZGyaQ= -go.opentelemetry.io/collector/pdata/testdata v0.125.0 h1:due1Hl0EEVRVwfCkiamRy5E8lS6yalv0lo8Zl/SJtGw= -go.opentelemetry.io/collector/pdata/testdata v0.125.0/go.mod h1:1GpEWlgdMrd+fWsBk37ZC2YmOP5YU3gFQ4rWuCu9g24= -go.opentelemetry.io/collector/pipeline v0.125.0 h1:oitBgcAFqntDB4ihQJUHJSQ8IHqKFpPkaTVbTYdIUzM= -go.opentelemetry.io/collector/pipeline v0.125.0/go.mod h1:TO02zju/K6E+oFIOdi372Wk0MXd+Szy72zcTsFQwXl4= -go.opentelemetry.io/collector/processor v1.31.0 h1:+u7sBUpnCBsHYoALp4hfr9VEjLHHYa4uKENGITe0K9Q= -go.opentelemetry.io/collector/processor v1.31.0/go.mod h1:5hDYJ7/hTdfd2tF2Rj5Hs6+mfyFz2O7CaPzVvW1qHQc= -go.opentelemetry.io/collector/processor/processorhelper v0.125.0 h1:QRpX7oFW88DAZhy+Q93npklRoaQr8ue0GKpeup7C/Fk= -go.opentelemetry.io/collector/processor/processorhelper v0.125.0/go.mod h1:oXRvslUuN62wErcoJrcEJYoTXu5wHyNyJsE+/a9Cc9s= -go.opentelemetry.io/collector/processor/processortest v0.125.0 h1:ZVAN4iZPDcWhpzKqnuok2NIuS5hwGVVQUOWkJFR12tA= -go.opentelemetry.io/collector/processor/processortest v0.125.0/go.mod h1:VAw0IRG35cWTBjBtreXeXJEgqkRegfjrH/EuLhNX2+I= -go.opentelemetry.io/collector/processor/xprocessor v0.125.0 h1:VWYPMW1VmDq6xB7M5SYjBpQCCIq3MhQ3W++wU47QpZM= -go.opentelemetry.io/collector/processor/xprocessor v0.125.0/go.mod h1:bCxUyFVlksANg8wjYZqWVsRB33lkLQ294rTrju/IZiM= -go.opentelemetry.io/collector/semconv v0.125.0 h1:SyRP617YGvNSWRSKMy7Lbk9RaJSR+qFAAfyxJOeZe4s= -go.opentelemetry.io/collector/semconv v0.125.0/go.mod h1:te6VQ4zZJO5Lp8dM2XIhDxDiL45mwX0YAQQWRQ0Qr9U= -go.opentelemetry.io/contrib/bridges/otelzap v0.10.0 h1:ojdSRDvjrnm30beHOmwsSvLpoRF40MlwNCA+Oo93kXU= -go.opentelemetry.io/contrib/bridges/otelzap v0.10.0/go.mod h1:oTTm4g7NEtHSV2i/0FeVdPaPgUIZPfQkFbq0vbzqnv0= +go.opentelemetry.io/collector/component v1.39.0 h1:GJw80zXURBG4h0sh97bPLEn2Ra+NAWUpskaooA0wru4= +go.opentelemetry.io/collector/component v1.39.0/go.mod h1:NPaMPTLQuxm5QaaWdqkxYKztC0bRdV+86Q9ir7xS/2k= +go.opentelemetry.io/collector/component/componentstatus v0.133.0 h1:fIcFKg+yPhpvOJKeMph9TtSC4DIGdIuNmxvUB0UGcoc= +go.opentelemetry.io/collector/component/componentstatus v0.133.0/go.mod h1:biQWms9cgXSZu3nb92Z0bA9uHh9lEhgmQ8CF4HLmu8Y= +go.opentelemetry.io/collector/component/componenttest v0.133.0 h1:mg54QqXC+GNqLHa9y6Efh3X5Di4XivjgJr6mzvfVQR8= +go.opentelemetry.io/collector/component/componenttest v0.133.0/go.mod h1:E+oqRK03WjG/b1aX1pd0CfTKh12MPTKbEBaBROp4w0M= +go.opentelemetry.io/collector/consumer v1.39.0 h1:Jc6la3uacHbznX5ORmh16Nddh23ZxBzoiNF2L0wD2Ks= +go.opentelemetry.io/collector/consumer v1.39.0/go.mod h1:tW2BXyntjvlKrRc+mwistt1KuC/b4mTfTkc8zWjeeRY= +go.opentelemetry.io/collector/consumer/consumertest v0.133.0 h1:MteqaGpgmHVHFqnB7A2voGleA2j51qJyVfX5x/wm+8I= +go.opentelemetry.io/collector/consumer/consumertest v0.133.0/go.mod h1:vHGknLn/RRUcMQuuBDt+SgrpDN46DBJyqRnWXm3gLwY= +go.opentelemetry.io/collector/consumer/xconsumer v0.133.0 h1:Xx4Yna/We4qDlbAla1nfxgkvujzWRuR8bqqwsLLvYSg= +go.opentelemetry.io/collector/consumer/xconsumer v0.133.0/go.mod h1:he874Md/0uAS2Fs+TDHAy10OBLRSw8233LdREizVvG4= +go.opentelemetry.io/collector/featuregate v1.46.0 h1:z3JlymFdWW6aDo9cYAJ6bCqT+OI2DlurJ9P8HqfuKWQ= +go.opentelemetry.io/collector/featuregate v1.46.0/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4= +go.opentelemetry.io/collector/internal/telemetry v0.133.0 h1:YxbckZC9HniNOZgnSofTOe0AB/bEsmISNdQeS+3CU3o= +go.opentelemetry.io/collector/internal/telemetry v0.133.0/go.mod h1:akUK7X6ZQ+CbbCjyXLv9y/EHt5jIy+J+nGoLvndZN14= +go.opentelemetry.io/collector/pdata v1.46.0 h1:XzhnIWNtc/gbOyFiewRvybR4s3phKHrWxL3yc/wVLDo= +go.opentelemetry.io/collector/pdata v1.46.0/go.mod h1:D2e3BWCUC/bUg29WNzCDVN7Ab0Gzk7hGXZL2pnrDOn0= +go.opentelemetry.io/collector/pdata/pprofile v0.140.0 h1:b9TZ6UnyzsT/ERQw2VKGi/NYLtKSmjG7cgQuc9wZt5s= +go.opentelemetry.io/collector/pdata/pprofile v0.140.0/go.mod h1:/2s/YBWGbu+r8MuKu5zas08iSqe+3P6xnbRpfE2DWAA= +go.opentelemetry.io/collector/pdata/testdata v0.133.0 h1:K0q47qecWVJf0sWbeWfifbJ72TiqR+A2PCsMkCEKvus= +go.opentelemetry.io/collector/pdata/testdata v0.133.0/go.mod h1:/emFpIox/mi7FucvsSn54KsiMh/iy7BUviqgURNVT6U= +go.opentelemetry.io/collector/pipeline v1.39.0 h1:CcEn30qdoHEzehFxgx0Ma0pWYGhrrIkRkcu218NG4V4= +go.opentelemetry.io/collector/pipeline v1.39.0/go.mod h1:NdM+ZqkPe9KahtOXG28RHTRQu4m/FD1i3Ew4qCRdOr8= +go.opentelemetry.io/collector/processor v1.39.0 h1:QwPJxJnFZwojo09Vfnvph7A27TauxxvA1koO6nr87O8= +go.opentelemetry.io/collector/processor v1.39.0/go.mod h1:WQWZqKmrlJcLjirnQOULxYgWV6h5oxK6FQNiFgw53i8= +go.opentelemetry.io/collector/processor/processorhelper v0.133.0 h1:3w/wvSmzyCvyNXjUQihH/VLQ+Tnzn3MlQNbv1AEoXiU= +go.opentelemetry.io/collector/processor/processorhelper v0.133.0/go.mod h1:lTlC8tGOBqkpdwGXCmaDnWXc2jqIrRUKvV7eK26Thc4= +go.opentelemetry.io/collector/processor/processortest v0.133.0 h1:PAuOr8Pwj/LAuey2LW1fix0vvnE+WwGpSF7bghaxjEE= +go.opentelemetry.io/collector/processor/processortest v0.133.0/go.mod h1:fEhWs9DCe431+iFke1WmlxqjcRDN25GLRXdktKAPyw8= +go.opentelemetry.io/collector/processor/xprocessor v0.133.0 h1:V5YMrXUgClh3awWOdigGXHxvq/Ira2wLDj4DJLqB+Eo= +go.opentelemetry.io/collector/processor/xprocessor v0.133.0/go.mod h1:5gDFI+pGIzoFQeBUM4QZ4E0B+SaU0e+2V7Td+ONoU4M= +go.opentelemetry.io/contrib/bridges/otelzap v0.12.0 h1:FGre0nZh5BSw7G73VpT3xs38HchsfPsa2aZtMp0NPOs= +go.opentelemetry.io/contrib/bridges/otelzap v0.12.0/go.mod h1:X2PYPViI2wTPIMIOBjG17KNybTzsrATnvPJ02kkz7LM= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk= go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= @@ -821,10 +813,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOL go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= @@ -839,8 +831,10 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1x go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= -go.opentelemetry.io/otel/log v0.11.0 h1:c24Hrlk5WJ8JWcwbQxdBqxZdOK7PcP/LFtOtwpDTe3Y= -go.opentelemetry.io/otel/log v0.11.0/go.mod h1:U/sxQ83FPmT29trrifhQg+Zj2lo1/IPN1PF6RTFqdwc= +go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= +go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= +go.opentelemetry.io/otel/log/logtest v0.13.0 h1:xxaIcgoEEtnwdgj6D6Uo9K/Dynz9jqIxSDu2YObJ69Q= +go.opentelemetry.io/otel/log/logtest v0.13.0/go.mod h1:+OrkmsAH38b+ygyag1tLjSFMYiES5UHggzrtY1IIEA8= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= @@ -853,6 +847,12 @@ go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZY go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= +go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -868,7 +868,6 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -882,8 +881,6 @@ golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -895,8 +892,6 @@ golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -914,8 +909,6 @@ golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -931,7 +924,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -984,8 +976,6 @@ golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= diff --git a/pkg/api/installations.go b/pkg/api/installations.go index c2d7e5321..981d6aeb6 100644 --- a/pkg/api/installations.go +++ b/pkg/api/installations.go @@ -105,7 +105,7 @@ func convertInstallation(installation *gqlclient.InstallationFragment) *Installa } func (client *client) OIDCProvider(id string, attributes *OidcProviderAttributes) error { - bindings := make([]*gqlclient.BindingAttributes, 0) + bindings := make([]*gqlclient.BindingAttributes, 0, len(attributes.Bindings)) for _, bind := range attributes.Bindings { groupId := bind.GroupId userId := bind.UserId diff --git a/pkg/api/versions.go b/pkg/api/versions.go index 5552e17b9..8f37e5754 100644 --- a/pkg/api/versions.go +++ b/pkg/api/versions.go @@ -18,7 +18,7 @@ type VersionAttributes struct { } func (client *client) UpdateVersion(spec *VersionSpec, tags []string) error { - tagAttrs := make([]*gqlclient.VersionTagAttributes, 0) + tagAttrs := make([]*gqlclient.VersionTagAttributes, 0, len(tags)) for _, tag := range tags { tagAttrs = append(tagAttrs, &gqlclient.VersionTagAttributes{ Tag: tag, diff --git a/pkg/common/args.go b/pkg/common/args.go new file mode 100644 index 000000000..805d0c79a --- /dev/null +++ b/pkg/common/args.go @@ -0,0 +1 @@ +package common diff --git a/pkg/config/config.go b/pkg/config/config.go index 5ad5e3224..aceb18b8d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -182,7 +182,8 @@ func PluralDir(p ...string) (string, error) { return "", err } - parts := []string{folder, pluralDir} + parts := make([]string, 0, 2+len(p)) + parts = append(parts, folder, pluralDir) parts = append(parts, p...) return filepath.Join(parts...), nil } diff --git a/pkg/console/pipelines.go b/pkg/console/pipelines.go index b1745042f..2061d61c2 100644 --- a/pkg/console/pipelines.go +++ b/pkg/console/pipelines.go @@ -98,7 +98,7 @@ func ConstructPipelineInput(input []byte) (string, *gqlclient.PipelineAttributes } func constructGates(edge PipelineEdge) []*gqlclient.PipelineGateAttributes { - res := make([]*gqlclient.PipelineGateAttributes, 0) + res := make([]*gqlclient.PipelineGateAttributes, 0, len(edge.Gates)) for _, g := range edge.Gates { res = append(res, &gqlclient.PipelineGateAttributes{ Name: g.Name, diff --git a/pkg/scm/github.go b/pkg/scm/github.go index bd78ad1d3..0b370b3e0 100644 --- a/pkg/scm/github.go +++ b/pkg/scm/github.go @@ -60,7 +60,7 @@ func (gh *Github) Setup() (con Context, err error) { return } - orgNames := make([]string, len(orgs)) + orgNames := make([]string, len(orgs), len(orgs)+1) for i, o := range orgs { orgNames[i] = *o.Login } diff --git a/pkg/scm/gitlab.go b/pkg/scm/gitlab.go index 281705074..d805dff61 100644 --- a/pkg/scm/gitlab.go +++ b/pkg/scm/gitlab.go @@ -64,7 +64,7 @@ func (gl *Gitlab) Setup() (con Context, err error) { return } - orgNames := make([]string, len(groups)) + orgNames := make([]string, len(groups), len(groups)+1) namespaces := make(map[string]int) for i, g := range groups { orgNames[i] = g.Path diff --git a/pkg/utils/map.go b/pkg/utils/map.go index 35a3ac272..e88a7a4ae 100644 --- a/pkg/utils/map.go +++ b/pkg/utils/map.go @@ -113,7 +113,7 @@ type SimpleType interface { } func Map[T any, R SimpleType](slice []T, mapper func(elem T) R) []R { - res := make([]R, 0) + res := make([]R, 0, len(slice)) for _, elem := range slice { res = append(res, mapper(elem)) diff --git a/test/lua/service_flag.lua b/test/lua/service_flag.lua new file mode 100644 index 000000000..a6f435b88 --- /dev/null +++ b/test/lua/service_flag.lua @@ -0,0 +1,11 @@ +values = {} +valuesFiles = {} + +values["serviceName"] = service["name"] +values["serviceNamePascal"] = service["Name"] +values["namespace"] = service["namespace"] +values["clusterName"] = cluster["name"] +values["clusterHandle"] = cluster["handle"] +values["configuration"] = configuration +values["contexts"] = contexts +values["imports"] = imports