From e3815762642a031d625284286f962006ce7a70c6 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Mon, 5 Jun 2023 11:52:55 +0300 Subject: [PATCH 001/173] Replace `login_before_ready` with `startup_script_behavior` (#125) --- docs/resources/agent.md | 3 +- provider/agent.go | 34 +++++++++++---- provider/agent_test.go | 94 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 11 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 9ee5c1d0..f3690194 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -50,12 +50,13 @@ resource "kubernetes_pod" "dev" { - `connection_timeout` (Number) Time in seconds until the agent is marked as timed out when a connection with the server cannot be established. A value of zero never marks the agent as timed out. - `dir` (String) The starting directory when a user creates a shell session. Defaults to $HOME. - `env` (Map of String) A mapping of environment variables to set inside the workspace. -- `login_before_ready` (Boolean) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. +- `login_before_ready` (Boolean, Deprecated) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. - `shutdown_script_timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. +- `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. - `startup_script_timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. diff --git a/provider/agent.go b/provider/agent.go index c5797081..90dd0525 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -16,7 +16,7 @@ import ( func agentResource() *schema.Resource { return &schema.Resource{ Description: "Use this resource to associate an agent.", - CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { + CreateContext: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { // This should be a real authentication token! resourceData.SetId(uuid.NewString()) err := resourceData.Set("token", uuid.NewString()) @@ -25,14 +25,14 @@ func agentResource() *schema.Resource { } return updateInitScript(resourceData, i) }, - ReadWithoutTimeout: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { + ReadWithoutTimeout: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { err := resourceData.Set("token", uuid.NewString()) if err != nil { return diag.FromErr(err) } return updateInitScript(resourceData, i) }, - DeleteContext: func(c context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + DeleteContext: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { return nil }, Schema: map[string]*schema.Schema{ @@ -131,11 +131,29 @@ func agentResource() *schema.Resource { Description: "The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd.", }, "login_before_ready": { - Type: schema.TypeBool, - Default: true, // Change default value to false in a future release. - ForceNew: true, - Optional: true, - Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in.", + // Note: When this is removed, "startup_script_behavior" should + // be set to "non-blocking" by default (instead of empty string). + Type: schema.TypeBool, + Default: true, + ForceNew: true, + Optional: true, + Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in.", + Deprecated: "Configure startup_script_behavior instead. This attribute will be removed in a future version of the provider.", + ConflictsWith: []string{"startup_script_behavior"}, + }, + "startup_script_behavior": { + // Note: Our default value is "non-blocking" but we do not set + // it here because we want to be able to differentiate between + // the user setting this or "login_before_ready". For all + // intents and purposes, until deprecation, setting + // "login_before_ready = false" is equivalent to setting + // "startup_script_behavior = blocking". + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Description: "This option sets the behavior of the `startup_script`. When set to \"blocking\", the startup_script must exit before the workspace is ready. When set to \"non-blocking\", the startup_script may run in the background and the workspace will be ready immediately. Default is \"non-blocking\", although \"blocking\" is recommended.", + ValidateFunc: validation.StringInSlice([]string{"blocking", "non-blocking"}, false), + ConflictsWith: []string{"login_before_ready"}, }, "metadata": { Type: schema.TypeList, diff --git a/provider/agent_test.go b/provider/agent_test.go index 2069247b..e3d96d1b 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -1,6 +1,7 @@ package provider_test import ( + "regexp" "testing" "github.com/coder/terraform-provider-coder/provider" @@ -36,7 +37,6 @@ func TestAgent(t *testing.T) { motd_file = "/etc/motd" shutdown_script = "echo bye bye" shutdown_script_timeout = 120 - login_before_ready = false } `, Check: func(state *terraform.State) error { @@ -58,7 +58,6 @@ func TestAgent(t *testing.T) { "motd_file", "shutdown_script", "shutdown_script_timeout", - "login_before_ready", } { value := resource.Primary.Attributes[key] t.Logf("%q = %q", key, value) @@ -71,6 +70,97 @@ func TestAgent(t *testing.T) { }) } +func TestAgent_StartupScriptBehavior(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + Name string + Config string + ExpectError *regexp.Regexp + Check func(state *terraform.ResourceState) + }{ + { + Name: "blocking", + Config: ` + resource "coder_agent" "new" { + os = "linux" + arch = "amd64" + startup_script_behavior = "blocking" + } + `, + Check: func(state *terraform.ResourceState) { + require.Equal(t, "blocking", state.Primary.Attributes["startup_script_behavior"]) + }, + }, + { + Name: "non-blocking", + Config: ` + resource "coder_agent" "new" { + os = "linux" + arch = "amd64" + startup_script_behavior = "non-blocking" + } + `, + Check: func(state *terraform.ResourceState) { + require.Equal(t, "non-blocking", state.Primary.Attributes["startup_script_behavior"]) + }, + }, + { + Name: "login_before_ready (deprecated)", + Config: ` + resource "coder_agent" "new" { + os = "linux" + arch = "amd64" + login_before_ready = false + } + `, + Check: func(state *terraform.ResourceState) { + require.Equal(t, "false", state.Primary.Attributes["login_before_ready"]) + // startup_script_behavior must be empty, this indicates that + // login_before_ready should be used instead. + require.Equal(t, "", state.Primary.Attributes["startup_script_behavior"]) + }, + }, + { + Name: "no login_before_ready with startup_script_behavior", + Config: ` + resource "coder_agent" "new" { + os = "linux" + arch = "amd64" + login_before_ready = false + startup_script_behavior = "blocking" + } + `, + ExpectError: regexp.MustCompile("conflicts with"), + }, + } { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: tc.Config, + ExpectError: tc.ExpectError, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["coder_agent.new"] + require.NotNil(t, resource) + if tc.Check != nil { + tc.Check(resource) + } + return nil + }, + }}, + }) + }) + } +} + func TestAgent_Instance(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ From 71cdbae95d880d02fbc6a48e0f6d83565ee59152 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 5 Jun 2023 15:43:27 +0200 Subject: [PATCH 002/173] coder_parameter: deprecate `legacy_variable` and `legacy_variable_name` (#126) --- docs/data-sources/parameter.md | 4 ++-- provider/parameter.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index c54e54ed..ef2e407c 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -25,8 +25,8 @@ Use this data source to configure editable options for workspaces. - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. -- `legacy_variable` (String) Reference to the Terraform variable. Coder will use it to lookup the default value. -- `legacy_variable_name` (String) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. +- `legacy_variable` (String, Deprecated) Reference to the Terraform variable. Coder will use it to lookup the default value. +- `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! - `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `type` (String) The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)". diff --git a/provider/parameter.go b/provider/parameter.go index f736579b..7bb4c465 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -336,12 +336,14 @@ func parameterDataSource() *schema.Resource { Optional: true, RequiredWith: []string{"legacy_variable"}, Description: "Name of the legacy Terraform variable. Coder will use it to lookup the variable value.", + Deprecated: "Effective from Coder v0.24.0, the parameter migration feature is no longer available. This attribute will be removed in the nearest future.", }, "legacy_variable": { Type: schema.TypeString, Optional: true, RequiredWith: []string{"legacy_variable_name"}, Description: "Reference to the Terraform variable. Coder will use it to lookup the default value.", + Deprecated: "Effective from Coder v0.24.0, the parameter migration feature is no longer available. This attribute will be removed in the nearest future.", }, }, } From cd41da2d3c6429f3f15afd590934ab2e5488e62a Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Mon, 5 Jun 2023 17:11:05 +0300 Subject: [PATCH 003/173] test: add tests for terraform version 1.4.* (#130) --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 97715835..2c4dbb0b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,6 +47,7 @@ jobs: - "1.1.*" - "1.2.*" - "1.3.*" + - "1.4.*" steps: - name: Set up Go uses: actions/setup-go@v3 From 09c3ada0df4c2cebeea2b606a2193fd004062add Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 28 Jun 2023 15:33:34 +0200 Subject: [PATCH 004/173] feat: add order to coder_parameter (#134) --- docs/data-sources/git_auth.md | 2 -- docs/data-sources/parameter.md | 3 +-- docs/data-sources/provisioner.md | 2 -- docs/data-sources/workspace.md | 2 -- docs/resources/agent.md | 2 -- docs/resources/agent_instance.md | 2 -- docs/resources/app.md | 2 -- docs/resources/metadata.md | 2 -- examples/resources/coder_parameter/resource.tf | 2 ++ provider/parameter.go | 9 +++++++++ provider/parameter_test.go | 2 ++ 11 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/data-sources/git_auth.md b/docs/data-sources/git_auth.md index 5573993d..53e01981 100644 --- a/docs/data-sources/git_auth.md +++ b/docs/data-sources/git_auth.md @@ -46,5 +46,3 @@ EOF ### Read-Only - `access_token` (String) The access token returned by the git authentication provider. This can be used to pre-authenticate command-line tools. - - diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index ef2e407c..180a7d7b 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -29,6 +29,7 @@ Use this data source to configure editable options for workspaces. - `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! - `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) +- `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). - `type` (String) The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)". - `validation` (Block List, Max: 1) Validate the input of a parameter. (see [below for nested schema](#nestedblock--validation)) @@ -67,5 +68,3 @@ Read-Only: - `max_disabled` (Boolean) Helper field to check if max is present - `min_disabled` (Boolean) Helper field to check if min is present - - diff --git a/docs/data-sources/provisioner.md b/docs/data-sources/provisioner.md index 47bdaf04..4316aeea 100644 --- a/docs/data-sources/provisioner.md +++ b/docs/data-sources/provisioner.md @@ -20,5 +20,3 @@ Use this data source to get information about the Coder provisioner. - `arch` (String) The architecture of the host. This exposes `runtime.GOARCH` (see https://pkg.go.dev/runtime#pkg-constants). - `id` (String) The ID of this resource. - `os` (String) The operating system of the host. This exposes `runtime.GOOS` (see https://pkg.go.dev/runtime#pkg-constants). - - diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index ffe49eb8..e7d58a5d 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -37,5 +37,3 @@ resource "kubernetes_pod" "dev" { - `owner_session_token` (String) Session token for interfacing with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. - `transition` (String) Either "start" or "stop". Use this to start/stop resources with "count". - - diff --git a/docs/resources/agent.md b/docs/resources/agent.md index f3690194..d073f7c5 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -79,5 +79,3 @@ Optional: - `display_name` (String) The user-facing name of this value. - `timeout` (Number) The maximum time the command is allowed to run in seconds. - - diff --git a/docs/resources/agent_instance.md b/docs/resources/agent_instance.md index 7eab0dde..fa8574fa 100644 --- a/docs/resources/agent_instance.md +++ b/docs/resources/agent_instance.md @@ -40,5 +40,3 @@ resource "coder_agent_instance" "dev" { ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/app.md b/docs/resources/app.md index e120f658..7b70bf6a 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -90,5 +90,3 @@ Required: - `interval` (Number) Duration in seconds to wait between healthcheck requests. - `threshold` (Number) Number of consecutive heathcheck failures before returning an unhealthy status. - `url` (String) HTTP address used determine the application readiness. A successful health check is a HTTP response code less than 500 returned before healthcheck.interval seconds. - - diff --git a/docs/resources/metadata.md b/docs/resources/metadata.md index 6edcd1d0..2d67e526 100644 --- a/docs/resources/metadata.md +++ b/docs/resources/metadata.md @@ -80,5 +80,3 @@ Optional: Read-Only: - `is_null` (Boolean) - - diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index a89ce1b8..15b747c4 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -45,12 +45,14 @@ data "coder_parameter" "cores" { type = "number" icon = "/icon/cpu.svg" default = 3 + order = 10 } data "coder_parameter" "disk_size" { name = "Disk Size" type = "number" default = "5" + order = 8 validation { # This can apply to number. min = 0 diff --git a/provider/parameter.go b/provider/parameter.go index 7bb4c465..e8cfd4c6 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -57,6 +57,8 @@ type Parameter struct { Validation []Validation Optional bool + Order int + LegacyVariableName string `mapstructure:"legacy_variable_name"` LegacyVariable string `mapstructure:"legacy_variable"` } @@ -90,6 +92,7 @@ func parameterDataSource() *schema.Resource { Option interface{} Validation interface{} Optional interface{} + Order interface{} LegacyVariableName interface{} LegacyVariable interface{} @@ -122,6 +125,7 @@ func parameterDataSource() *schema.Resource { rd.Set("optional", val) return val }(), + Order: rd.Get("order"), LegacyVariableName: rd.Get("legacy_variable_name"), LegacyVariable: rd.Get("legacy_variable"), }, ¶meter) @@ -331,6 +335,11 @@ func parameterDataSource() *schema.Resource { Computed: true, Description: "Whether this value is optional.", }, + "order": { + Type: schema.TypeInt, + Optional: true, + Description: "The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order).", + }, "legacy_variable_name": { Type: schema.TypeString, Optional: true, diff --git a/provider/parameter_test.go b/provider/parameter_test.go index d749592b..f591eeff 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -43,6 +43,7 @@ func TestParameter(t *testing.T) { icon = "/icon/east.svg" description = "Select for east!" } + order = 5 } `, Check: func(state *terraform.ResourceState) { @@ -62,6 +63,7 @@ func TestParameter(t *testing.T) { "option.1.value": "us-east1-a", "option.1.icon": "/icon/east.svg", "option.1.description": "Select for east!", + "order": "5", } { require.Equal(t, value, attrs[key]) } From 9236b0e6ed3e42cf7871eb961af07b39f54e9a52 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 30 Jun 2023 09:36:17 +0300 Subject: [PATCH 005/173] ci: include terraform 1.5.* to tests (#135) The title says it all. --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2c4dbb0b..aece554e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,6 +48,7 @@ jobs: - "1.2.*" - "1.3.*" - "1.4.*" + - "1.5.*" steps: - name: Set up Go uses: actions/setup-go@v3 From abc4f9883c408a1b1f47c47deb0ddb35c693c719 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 6 Jul 2023 10:38:52 +0200 Subject: [PATCH 006/173] feat: support ephemeral parameters (#138) --- docs/data-sources/parameter.md | 1 + examples/resources/coder_parameter/resource.tf | 6 ++++-- provider/parameter.go | 16 ++++++++++++++-- provider/parameter_test.go | 13 +++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 180a7d7b..100c4f91 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -24,6 +24,7 @@ Use this data source to configure editable options for workspaces. - `default` (String) A default value for the parameter. - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. +- `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `legacy_variable` (String, Deprecated) Reference to the Terraform variable. Coder will use it to lookup the default value. - `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index 15b747c4..ca2f9ec4 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -74,8 +74,10 @@ data "coder_parameter" "cat_lives" { } data "coder_parameter" "fairy_tale" { - name = "Fairy Tale" - type = "string" + name = "Fairy Tale" + type = "string" + mutable = true + ephemeral = true } data "coder_parameter" "users" { diff --git a/provider/parameter.go b/provider/parameter.go index e8cfd4c6..da09720a 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -56,8 +56,8 @@ type Parameter struct { Option []Option Validation []Validation Optional bool - - Order int + Order int + Ephemeral bool LegacyVariableName string `mapstructure:"legacy_variable_name"` LegacyVariable string `mapstructure:"legacy_variable"` @@ -93,6 +93,7 @@ func parameterDataSource() *schema.Resource { Validation interface{} Optional interface{} Order interface{} + Ephemeral interface{} LegacyVariableName interface{} LegacyVariable interface{} @@ -126,6 +127,7 @@ func parameterDataSource() *schema.Resource { return val }(), Order: rd.Get("order"), + Ephemeral: rd.Get("ephemeral"), LegacyVariableName: rd.Get("legacy_variable_name"), LegacyVariable: rd.Get("legacy_variable"), }, ¶meter) @@ -146,6 +148,10 @@ func parameterDataSource() *schema.Resource { } rd.Set("value", value) + if !parameter.Mutable && parameter.Ephemeral { + return diag.Errorf("parameter can't be immutable and ephemeral") + } + if len(parameter.Validation) == 1 { validation := ¶meter.Validation[0] err = validation.Valid(parameter.Type, value) @@ -340,6 +346,12 @@ func parameterDataSource() *schema.Resource { Optional: true, Description: "The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order).", }, + "ephemeral": { + Type: schema.TypeBool, + Default: false, + Optional: true, + Description: "The value of an ephemeral parameter will not be preserved between consecutive workspace builds.", + }, "legacy_variable_name": { Type: schema.TypeString, Optional: true, diff --git a/provider/parameter_test.go b/provider/parameter_test.go index f591eeff..78075c18 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -44,6 +44,7 @@ func TestParameter(t *testing.T) { description = "Select for east!" } order = 5 + ephemeral = true } `, Check: func(state *terraform.ResourceState) { @@ -64,6 +65,7 @@ func TestParameter(t *testing.T) { "option.1.icon": "/icon/east.svg", "option.1.description": "Select for east!", "order": "5", + "ephemeral": "true", } { require.Equal(t, value, attrs[key]) } @@ -602,6 +604,17 @@ data "coder_parameter" "region" { } `, ExpectError: regexp.MustCompile("a min cannot be specified for a bool type"), + }, { + Name: "ImmutableEphemeralError", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "string" + mutable = false + ephemeral = true + } + `, + ExpectError: regexp.MustCompile("parameter can't be immutable and ephemeral"), }} { tc := tc t.Run(tc.Name, func(t *testing.T) { From 5d01ad6f0f09924efb67da75626dd6c22b9822f7 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 6 Jul 2023 12:03:38 +0200 Subject: [PATCH 007/173] feat: drop support for legacy variables (#140) --- docs/data-sources/parameter.md | 2 - docs/index.md | 2 +- .../resources/coder_parameter/resource.tf | 4 +- .../coder_parameter_migration/resource.tf | 14 ----- provider/decode_test.go | 17 ++---- provider/examples_test.go | 14 ----- provider/parameter.go | 44 +++------------- provider/parameter_test.go | 52 ------------------- provider/provider.go | 4 +- 9 files changed, 15 insertions(+), 138 deletions(-) delete mode 100644 examples/resources/coder_parameter_migration/resource.tf diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 100c4f91..fc8100e7 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -26,8 +26,6 @@ Use this data source to configure editable options for workspaces. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. - `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. -- `legacy_variable` (String, Deprecated) Reference to the Terraform variable. Coder will use it to lookup the default value. -- `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! - `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). diff --git a/docs/index.md b/docs/index.md index 154423c1..13bf6b44 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,5 +62,5 @@ resource "google_compute_instance" "dev" { ### Optional -- `feature_use_managed_variables` (Boolean) Feature: use managed Terraform variables. If disabled, Terraform variables will be included in legacy Parameter Schema. +- `feature_use_managed_variables` (Boolean, Deprecated) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. - `url` (String) The URL to access Coder. \ No newline at end of file diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index ca2f9ec4..bb986183 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -1,6 +1,4 @@ -provider "coder" { - feature_use_managed_variables = true -} +provider "coder" {} data "coder_parameter" "example" { name = "Region" diff --git a/examples/resources/coder_parameter_migration/resource.tf b/examples/resources/coder_parameter_migration/resource.tf deleted file mode 100644 index 1317dce1..00000000 --- a/examples/resources/coder_parameter_migration/resource.tf +++ /dev/null @@ -1,14 +0,0 @@ -provider "coder" {} - -variable "old_account_name" { - type = string - default = "fake-user" # for testing purposes, no need to set via env TF_... -} - -data "coder_parameter" "account_name" { - name = "Account Name" - type = "string" - - legacy_variable_name = "old_account_name" - legacy_variable = var.old_account_name -} \ No newline at end of file diff --git a/provider/decode_test.go b/provider/decode_test.go index de56922c..a5e20b14 100644 --- a/provider/decode_test.go +++ b/provider/decode_test.go @@ -11,19 +11,12 @@ import ( ) func TestDecode(t *testing.T) { - const ( - legacyVariable = "Legacy Variable" - legacyVariableName = "Legacy Variable Name" - - displayName = "Display Name" - ) + const displayName = "Display Name" aMap := map[string]interface{}{ - "name": "Parameter Name", - "type": "number", - "display_name": displayName, - "legacy_variable": legacyVariable, - "legacy_variable_name": legacyVariableName, + "name": "Parameter Name", + "type": "number", + "display_name": displayName, "validation": []map[string]interface{}{ { "min": nil, @@ -38,8 +31,6 @@ func TestDecode(t *testing.T) { err := mapstructure.Decode(aMap, ¶m) require.NoError(t, err) assert.Equal(t, displayName, param.DisplayName) - assert.Equal(t, legacyVariable, param.LegacyVariable) - assert.Equal(t, legacyVariableName, param.LegacyVariableName) assert.Equal(t, 5, param.Validation[0].Max) assert.True(t, param.Validation[0].MaxDisabled) assert.Equal(t, 0, param.Validation[0].Min) diff --git a/provider/examples_test.go b/provider/examples_test.go index 12f32800..263e65ce 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -26,20 +26,6 @@ func TestExamples(t *testing.T) { }}, }) }) - - t.Run("coder_parameter_migration", func(t *testing.T) { - t.Parallel() - - resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, - Steps: []resource.TestStep{{ - Config: mustReadFile(t, "../examples/resources/coder_parameter_migration/resource.tf"), - }}, - }) - }) } func mustReadFile(t *testing.T, path string) string { diff --git a/provider/parameter.go b/provider/parameter.go index da09720a..5791a323 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -58,9 +58,6 @@ type Parameter struct { Optional bool Order int Ephemeral bool - - LegacyVariableName string `mapstructure:"legacy_variable_name"` - LegacyVariable string `mapstructure:"legacy_variable"` } func parameterDataSource() *schema.Resource { @@ -94,9 +91,6 @@ func parameterDataSource() *schema.Resource { Optional interface{} Order interface{} Ephemeral interface{} - - LegacyVariableName interface{} - LegacyVariable interface{} }{ Value: rd.Get("value"), Name: rd.Get("name"), @@ -104,20 +98,10 @@ func parameterDataSource() *schema.Resource { Description: rd.Get("description"), Type: rd.Get("type"), Mutable: rd.Get("mutable"), - Default: func() interface{} { - standardMode := rd.GetRawConfig().AsValueMap()["legacy_variable"].IsNull() - if standardMode { - return rd.Get("default") - } - - // legacy variable is linked - legacyVariable := rd.GetRawConfig().AsValueMap()["legacy_variable"].AsString() - rd.Set("default", legacyVariable) - return legacyVariable - }(), - Icon: rd.Get("icon"), - Option: rd.Get("option"), - Validation: fixedValidation, + Default: rd.Get("default"), + Icon: rd.Get("icon"), + Option: rd.Get("option"), + Validation: fixedValidation, Optional: func() bool { // This hack allows for checking if the "default" field is present in the .tf file. // If "default" is missing or is "null", then it means that this field is required, @@ -126,10 +110,8 @@ func parameterDataSource() *schema.Resource { rd.Set("optional", val) return val }(), - Order: rd.Get("order"), - Ephemeral: rd.Get("ephemeral"), - LegacyVariableName: rd.Get("legacy_variable_name"), - LegacyVariable: rd.Get("legacy_variable"), + Order: rd.Get("order"), + Ephemeral: rd.Get("ephemeral"), }, ¶meter) if err != nil { return diag.Errorf("decode parameter: %s", err) @@ -352,20 +334,6 @@ func parameterDataSource() *schema.Resource { Optional: true, Description: "The value of an ephemeral parameter will not be preserved between consecutive workspace builds.", }, - "legacy_variable_name": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"legacy_variable"}, - Description: "Name of the legacy Terraform variable. Coder will use it to lookup the variable value.", - Deprecated: "Effective from Coder v0.24.0, the parameter migration feature is no longer available. This attribute will be removed in the nearest future.", - }, - "legacy_variable": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"legacy_variable_name"}, - Description: "Reference to the Terraform variable. Coder will use it to lookup the default value.", - Deprecated: "Effective from Coder v0.24.0, the parameter migration feature is no longer available. This attribute will be removed in the nearest future.", - }, }, } } diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 78075c18..4e21cea8 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -353,32 +353,6 @@ func TestParameter(t *testing.T) { require.Equal(t, expected, state.Primary.Attributes[key]) } }, - }, { - Name: "LegacyVariable", - Config: ` -variable "old_region" { - type = string - default = "fake-region" # for testing purposes, no need to set via env TF_... -} - -data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "will-be-ignored" - legacy_variable_name = "old_region" - legacy_variable = var.old_region -}`, - Check: func(state *terraform.ResourceState) { - for key, expected := range map[string]string{ - "name": "Region", - "type": "string", - "default": "fake-region", - "legacy_variable_name": "old_region", - "legacy_variable": "fake-region", - } { - require.Equal(t, expected, state.Primary.Attributes[key]) - } - }, }, { Name: "ListOfStrings", Config: ` @@ -398,32 +372,6 @@ data "coder_parameter" "region" { require.Equal(t, expected, attributeValue) } }, - }, { - Name: "ListOfStringsButMigrated", - Config: ` -variable "old_region" { - type = list(string) - default = ["us-west-1a"] # for testing purposes, no need to set via env TF_... -} - -data "coder_parameter" "region" { - name = "Region" - type = "list(string)" - default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]" - legacy_variable_name = "old_region" - legacy_variable = jsonencode(var.old_region) -}`, - Check: func(state *terraform.ResourceState) { - for key, expected := range map[string]string{ - "name": "Region", - "type": "list(string)", - "default": `["us-west-1a"]`, - } { - attributeValue, ok := state.Primary.Attributes[key] - require.True(t, ok, "attribute %q is expected", key) - require.Equal(t, expected, attributeValue) - } - }, }, { Name: "NumberValidation_Max", Config: ` diff --git a/provider/provider.go b/provider/provider.go index a77774cd..32058b5b 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -37,8 +37,10 @@ func New() *schema.Provider { }, "feature_use_managed_variables": { Type: schema.TypeBool, - Description: "Feature: use managed Terraform variables. If disabled, Terraform variables will be included in legacy Parameter Schema.", + Description: "Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables.", + Default: true, Optional: true, + Deprecated: "Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.", }, }, ConfigureContextFunc: func(c context.Context, resourceData *schema.ResourceData) (interface{}, diag.Diagnostics) { From 1882c77d5dd9df1be57f0e1075d9eaa27ac6f71c Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 18 Jul 2023 10:43:59 +0200 Subject: [PATCH 008/173] feat: ephemeral parameters must be optional (#141) --- examples/resources/coder_parameter/resource.tf | 1 + provider/parameter.go | 4 ++++ provider/parameter_test.go | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index bb986183..3c674f1c 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -75,6 +75,7 @@ data "coder_parameter" "fairy_tale" { name = "Fairy Tale" type = "string" mutable = true + default = "Hansel and Gretel" ephemeral = true } diff --git a/provider/parameter.go b/provider/parameter.go index 5791a323..339bb017 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -134,6 +134,10 @@ func parameterDataSource() *schema.Resource { return diag.Errorf("parameter can't be immutable and ephemeral") } + if !parameter.Optional && parameter.Ephemeral { + return diag.Errorf("ephemeral parameter requires the default property") + } + if len(parameter.Validation) == 1 { validation := ¶meter.Validation[0] err = validation.Valid(parameter.Type, value) diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 4e21cea8..48cf4829 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -31,6 +31,7 @@ func TestParameter(t *testing.T) { EOT mutable = true icon = "/icon/region.svg" + default = "us-east1-a" option { name = "US Central" value = "us-central1-a" @@ -65,6 +66,7 @@ func TestParameter(t *testing.T) { "option.1.icon": "/icon/east.svg", "option.1.description": "Select for east!", "order": "5", + "default": "us-east1-a", "ephemeral": "true", } { require.Equal(t, value, attrs[key]) @@ -558,11 +560,23 @@ data "coder_parameter" "region" { data "coder_parameter" "region" { name = "Region" type = "string" + default = "abc" mutable = false ephemeral = true } `, ExpectError: regexp.MustCompile("parameter can't be immutable and ephemeral"), + }, { + Name: "RequiredEphemeralError", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "string" + mutable = true + ephemeral = true + } + `, + ExpectError: regexp.MustCompile("ephemeral parameter requires the default property"), }} { tc := tc t.Run(tc.Name, func(t *testing.T) { From 7dbd512a111710302a66c4047b349504018308f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:29:06 -0500 Subject: [PATCH 009/173] build(deps): Bump golang.org/x/net from 0.0.0-20220127200216-cd36cc0744dd to 0.7.0 (#108) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index db38910d..13cc13b3 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/google/uuid v1.3.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 + github.com/mitchellh/mapstructure v1.5.0 github.com/stretchr/testify v1.8.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) @@ -42,7 +43,6 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -52,9 +52,9 @@ require ( github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect - golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf // indirect google.golang.org/grpc v1.48.0 // indirect diff --git a/go.sum b/go.sum index 318f05a2..8518f5e4 100644 --- a/go.sum +++ b/go.sum @@ -237,6 +237,7 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= @@ -251,6 +252,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -258,6 +260,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -278,8 +281,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -288,6 +292,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -314,18 +319,22 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -333,6 +342,7 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 080a1710fe45384e95a255ec8faa087f87991ccf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:45:08 -0500 Subject: [PATCH 010/173] build(deps): Bump google.golang.org/grpc from 1.48.0 to 1.53.0 (#139) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 +- go.sum | 928 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 928 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 13cc13b3..dea193da 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.13.0 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -56,8 +56,8 @@ require ( golang.org/x/sys v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf // indirect - google.golang.org/grpc v1.48.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.53.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8518f5e4..78a97609 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,397 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= @@ -26,15 +413,27 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6 github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -44,10 +443,16 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -62,16 +467,32 @@ github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -81,21 +502,69 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -121,6 +590,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= @@ -146,6 +617,9 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -153,9 +627,13 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -167,6 +645,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -200,10 +680,14 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -214,19 +698,27 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -236,7 +728,11 @@ github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37w github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/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/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= @@ -244,23 +740,68 @@ github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +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.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -269,110 +810,480 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/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-20220601150217-0de741cfad7f/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.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf h1:SVYXkUz2yZS9FWb2Gm8ivSlbNQzL2Z/NpPKE3RG2jWk= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -387,8 +1298,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -406,4 +1318,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From d53ec6374627ffe15e173f5cda0ee2d06766c2c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:46:50 -0500 Subject: [PATCH 011/173] build(deps): Bump actions/setup-go from 3 to 4 (#131) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a7e84e32..749c6c7b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: run: git fetch --prune --unshallow - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: 1.17 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aece554e..f807bf64 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: timeout-minutes: 5 steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: "1.20" id: go @@ -51,7 +51,7 @@ jobs: - "1.5.*" steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: "1.20" id: go @@ -81,7 +81,7 @@ jobs: timeout-minutes: 5 steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: "1.20" id: go From 5eb83e90478987464fb549e7ecf9a92652016bca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:47:23 -0500 Subject: [PATCH 012/173] build(deps): Bump contributor-assistant/github-action from 2.2.1 to 2.3.0 (#95) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 81aafca3..51b35c7b 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.2.1 + uses: contributor-assistant/github-action@v2.3.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From ddf26e878dd017d9d7adc1e9532dfb3bb12d1c1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:02:48 -0500 Subject: [PATCH 013/173] build(deps): Bump github.com/stretchr/testify from 1.8.0 to 1.8.4 (#128) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dea193da..9d391a3d 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.4 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index 78a97609..f7387f09 100644 --- a/go.sum +++ b/go.sum @@ -715,10 +715,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= From 8ec2e1e660fc2ea5de0d44414825c8f8f6450b80 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Tue, 18 Jul 2023 18:03:09 +0300 Subject: [PATCH 014/173] chore: bump go to 1.20 in release.yml (#143) Co-authored-by: Colin Adler --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 749c6c7b..ee382141 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.17 + go-version: 1.20.6 - name: Import GPG key id: import_gpg From 09b1ab7bb2a7e59be58654d9c8495e8751921ba8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:06:19 -0500 Subject: [PATCH 015/173] build(deps): Bump crazy-max/ghaction-import-gpg from 5.1.0 to 5.3.0 (#129) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee382141..89cfffb0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5.1.0 + uses: crazy-max/ghaction-import-gpg@v5.3.0 with: # These secrets will need to be configured for the repository: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} From 9d8fa003e6bf001798739a8b820828ac1339fd12 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Tue, 18 Jul 2023 10:07:31 -0500 Subject: [PATCH 016/173] chore: update gomod version to 1.20 (#142) --- .github/workflows/test.yml | 3 + go.mod | 2 +- go.sum | 1073 ------------------------------------ 3 files changed, 4 insertions(+), 1074 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f807bf64..bdb30fe1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,10 @@ on: pull_request: paths-ignore: - "README.md" + push: + branches: + - "main" paths-ignore: - "README.md" diff --git a/go.mod b/go.mod index 9d391a3d..da846746 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/coder/terraform-provider-coder -go 1.17 +go 1.20 require ( github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index f7387f09..d98eda60 100644 --- a/go.sum +++ b/go.sum @@ -1,463 +1,30 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= -github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= @@ -467,104 +34,22 @@ github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -576,7 +61,6 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -590,8 +74,6 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= @@ -604,7 +86,6 @@ github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw= github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M= -github.com/hashicorp/terraform-plugin-log v0.6.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 h1:+KxZULPsbjpAVoP0WNj/8aVW6EqpcX5JcUcQ5wl7Da4= @@ -613,27 +94,17 @@ github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b57 github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -644,16 +115,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -661,11 +126,8 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -674,49 +136,28 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -728,577 +169,74 @@ github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37w github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/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/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/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-20220601150217-0de741cfad7f/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.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1311,19 +249,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 9ff00d69f11fc7f8d7b18bc65dcea9b0e83f1bd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:08:44 -0500 Subject: [PATCH 017/173] build(deps): Bump goreleaser/goreleaser-action from 3.0.0 to 4.3.0 (#132) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 89cfffb0..f1b612b1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v3.0.0 + uses: goreleaser/goreleaser-action@v4.3.0 with: version: latest args: release --rm-dist From 188ffef2db4bc9f5fd745aba271ec0925d2e9666 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 19 Jul 2023 15:52:43 +0300 Subject: [PATCH 018/173] chore: calrify the format of `url` for `coder_app` resource (#145) * chore: calrify the format of `url` for `coder_app` resource A user has suggested to clarify the format of `url` in `coder_app` resource. See : https://github.com/coder/coder/discussions/8574#discussioncomment-6486344 for related discussion. * Update app.go * make gen * Update app.go * make gen --- docs/resources/app.md | 2 +- provider/app.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/resources/app.md b/docs/resources/app.md index 7b70bf6a..53a8c127 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -76,7 +76,7 @@ resource "coder_app" "intellij" { - `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. - `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false. -- `url` (String) A URL to be proxied to from inside the workspace. Either "command" or "url" may be specified, but not both. +- `url` (String) A URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both. ### Read-Only diff --git a/provider/app.go b/provider/app.go index 0d937dd0..d8471788 100644 --- a/provider/app.go +++ b/provider/app.go @@ -151,6 +151,7 @@ func appResource() *schema.Resource { "url": { Type: schema.TypeString, Description: "A URL to be proxied to from inside the workspace. " + + "This should be of the form \"http://localhost:PORT[/SUBPATH]\". " + "Either \"command\" or \"url\" may be specified, but not both.", ForceNew: true, Optional: true, From 233ea60c21a9e336c9bacbc1acaf7c65e7aa44d4 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 30 Aug 2023 14:02:27 -0500 Subject: [PATCH 019/173] feat: add `default_apps` field to `coder_agent` resource (#147) - Enables a template admin to configure which apps are displayed to the user in the dashboard. --- docs/data-sources/workspace.md | 2 +- docs/resources/agent.md | 19 +++ examples/resources/coder_agent/resource.tf | 6 + provider/agent.go | 77 +++++++++ provider/agent_test.go | 182 ++++++++++++++++++++- provider/examples_test.go | 3 +- provider/workspace.go | 2 +- 7 files changed, 287 insertions(+), 4 deletions(-) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index e7d58a5d..c736f78a 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -34,6 +34,6 @@ resource "kubernetes_pod" "dev" { - `owner_email` (String) Email address of the workspace owner. - `owner_id` (String) UUID of the workspace owner. - `owner_oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String) Session token for interfacing with a Coder deployment. It is regenerated everytime a workspace is started. +- `owner_session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. - `transition` (String) Either "start" or "stop". Use this to start/stop resources with "count". diff --git a/docs/resources/agent.md b/docs/resources/agent.md index d073f7c5..7e20ade4 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -20,6 +20,12 @@ resource "coder_agent" "dev" { os = "linux" arch = "amd64" dir = "/workspace" + display_apps { + vscode = true + vscode_insiders = false + web_terminal = true + ssh_helper = false + } } resource "kubernetes_pod" "dev" { @@ -49,6 +55,7 @@ resource "kubernetes_pod" "dev" { - `auth` (String) The authentication type the agent will use. Must be one of: "token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity". - `connection_timeout` (Number) Time in seconds until the agent is marked as timed out when a connection with the server cannot be established. A value of zero never marks the agent as timed out. - `dir` (String) The starting directory when a user creates a shell session. Defaults to $HOME. +- `display_apps` (Block Set, Max: 1) The list of built-in apps to display in the agent bar. (see [below for nested schema](#nestedblock--display_apps)) - `env` (Map of String) A mapping of environment variables to set inside the workspace. - `login_before_ready` (Boolean, Deprecated) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) @@ -66,6 +73,18 @@ resource "kubernetes_pod" "dev" { - `init_script` (String) Run this script on startup of an instance to initialize the agent. - `token` (String, Sensitive) Set the environment variable "CODER_AGENT_TOKEN" with this token to authenticate an agent. + +### Nested Schema for `display_apps` + +Optional: + +- `port_forwarding_helper` (Boolean) Display the port-forwarding helper button in the agent bar. +- `ssh_helper` (Boolean) Display the SSH helper button in the agent bar. +- `vscode` (Boolean) Display the VSCode Desktop app in the agent bar. +- `vscode_insiders` (Boolean) Display the VSCode Insiders app in the agent bar. +- `web_terminal` (Boolean) Display the web terminal app in the agent bar. + + ### Nested Schema for `metadata` diff --git a/examples/resources/coder_agent/resource.tf b/examples/resources/coder_agent/resource.tf index 2f1503fd..d5235a18 100644 --- a/examples/resources/coder_agent/resource.tf +++ b/examples/resources/coder_agent/resource.tf @@ -5,6 +5,12 @@ resource "coder_agent" "dev" { os = "linux" arch = "amd64" dir = "/workspace" + display_apps { + vscode = true + vscode_insiders = false + web_terminal = true + ssh_helper = false + } } resource "kubernetes_pod" "dev" { diff --git a/provider/agent.go b/provider/agent.go index 90dd0525..9b5ac3f3 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -23,6 +23,21 @@ func agentResource() *schema.Resource { if err != nil { return diag.FromErr(err) } + + if _, ok := resourceData.GetOk("display_apps"); !ok { + err = resourceData.Set("display_apps", []interface{}{ + map[string]bool{ + "vscode": true, + "vscode_insiders": false, + "web_terminal": true, + "ssh_helper": true, + "port_forwarding_helper": true, + }, + }) + if err != nil { + return diag.FromErr(err) + } + } return updateInitScript(resourceData, i) }, ReadWithoutTimeout: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { @@ -30,6 +45,21 @@ func agentResource() *schema.Resource { if err != nil { return diag.FromErr(err) } + if _, ok := resourceData.GetOk("display_apps"); !ok { + err = resourceData.Set("display_apps", []interface{}{ + map[string]bool{ + "vscode": true, + "vscode_insiders": false, + "web_terminal": true, + "ssh_helper": true, + "port_forwarding_helper": true, + }, + }) + if err != nil { + return diag.FromErr(err) + } + } + return updateInitScript(resourceData, i) }, DeleteContext: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { @@ -198,6 +228,53 @@ func agentResource() *schema.Resource { }, }, }, + "display_apps": { + Type: schema.TypeSet, + Description: "The list of built-in apps to display in the agent bar.", + ForceNew: true, + Optional: true, + MaxItems: 1, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vscode": { + Type: schema.TypeBool, + Description: "Display the VSCode Desktop app in the agent bar.", + ForceNew: true, + Optional: true, + Default: true, + }, + "vscode_insiders": { + Type: schema.TypeBool, + Description: "Display the VSCode Insiders app in the agent bar.", + ForceNew: true, + Optional: true, + Default: false, + }, + "web_terminal": { + Type: schema.TypeBool, + Description: "Display the web terminal app in the agent bar.", + ForceNew: true, + Optional: true, + Default: true, + }, + "port_forwarding_helper": { + Type: schema.TypeBool, + Description: "Display the port-forwarding helper button in the agent bar.", + ForceNew: true, + Optional: true, + Default: true, + }, + "ssh_helper": { + Type: schema.TypeBool, + Description: "Display the SSH helper button in the agent bar.", + ForceNew: true, + Optional: true, + Default: true, + }, + }, + }, + }, }, } } diff --git a/provider/agent_test.go b/provider/agent_test.go index e3d96d1b..9026385c 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -1,14 +1,16 @@ package provider_test import ( + "fmt" "regexp" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" + + "github.com/coder/terraform-provider-coder/provider" ) func TestAgent(t *testing.T) { @@ -247,3 +249,181 @@ func TestAgent_Metadata(t *testing.T) { }}, }) } + +func TestAgent_DisplayApps(t *testing.T) { + t.Parallel() + t.Run("OK", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + // Test the fields with non-default values. + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + display_apps { + vscode = false + vscode_insiders = true + web_terminal = false + port_forwarding_helper = false + ssh_helper = false + } + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + t.Logf("resource: %v", resource.Primary.Attributes) + + for _, app := range []string{ + "web_terminal", + "vscode_insiders", + "vscode", + "port_forwarding_helper", + "ssh_helper", + } { + key := fmt.Sprintf("display_apps.0.%s", app) + if app == "vscode_insiders" { + require.Equal(t, "true", resource.Primary.Attributes[key]) + } else { + require.Equal(t, "false", resource.Primary.Attributes[key]) + } + } + return nil + }, + }}, + }) + }) + + t.Run("Subset", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + // Test the fields with non-default values. + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + display_apps { + vscode_insiders = true + web_terminal = true + } + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + t.Logf("resource: %v", resource.Primary.Attributes) + + for _, app := range []string{ + "web_terminal", + "vscode_insiders", + "vscode", + "port_forwarding_helper", + "ssh_helper", + } { + key := fmt.Sprintf("display_apps.0.%s", app) + require.Equal(t, "true", resource.Primary.Attributes[key]) + } + return nil + }, + }}, + }) + }) + + // Assert all the defaults are set correctly. + t.Run("Omitted", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + t.Logf("resource: %v", resource.Primary.Attributes) + + for _, app := range []string{ + "web_terminal", + "vscode_insiders", + "vscode", + "port_forwarding_helper", + "ssh_helper", + } { + key := fmt.Sprintf("display_apps.0.%s", app) + if app == "vscode_insiders" { + require.Equal(t, "false", resource.Primary.Attributes[key]) + } else { + require.Equal(t, "true", resource.Primary.Attributes[key]) + } + } + return nil + }, + }}, + }) + }) + + t.Run("InvalidApp", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + // Test the fields with non-default values. + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + display_apps { + fake_app = false + vscode_insiders = true + web_terminal = false + port_forwarding_helper = false + ssh_helper = false + } + } + `, + ExpectError: regexp.MustCompile(`An argument named "fake_app" is not expected here.`), + }}, + }) + }) + +} diff --git a/provider/examples_test.go b/provider/examples_test.go index 263e65ce..9be7ce02 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -4,10 +4,11 @@ import ( "os" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/stretchr/testify/require" + + "github.com/coder/terraform-provider-coder/provider" ) func TestExamples(t *testing.T) { diff --git a/provider/workspace.go b/provider/workspace.go index 47f0e799..995cb6e4 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -137,7 +137,7 @@ func workspaceDataSource() *schema.Resource { "owner_session_token": { Type: schema.TypeString, Computed: true, - Description: "Session token for interfacing with a Coder deployment. It is regenerated everytime a workspace is started.", + Description: "Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started.", }, }, } From 949577713c403990c1bdec53c502a455081d5193 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 13 Sep 2023 09:27:12 -0500 Subject: [PATCH 020/173] feat: add `coder_script` (#154) * feat: add `coder_script` See coder/coder#9287 I decided to drop the `agent` portion from the name. It seemed inconsistent with `coder_app`. * Fix docs --- docs/resources/script.md | 36 ++++++++++++++++ provider/provider.go | 1 + provider/script.go | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 docs/resources/script.md create mode 100644 provider/script.go diff --git a/docs/resources/script.md b/docs/resources/script.md new file mode 100644 index 00000000..51213aac --- /dev/null +++ b/docs/resources/script.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_script Resource - terraform-provider-coder" +subcategory: "" +description: |- + Use this resource to run a script from an agent. +--- + +# coder_script (Resource) + +Use this resource to run a script from an agent. + + + + +## Schema + +### Required + +- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `display_name` (String) The display name of the script to display logs in the dashboard. +- `script` (String) The script to run. + +### Optional + +- `cron` (String) The cron schedule to run the script on. This is a cron expression. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. +- `log_path` (String) The path of a file to write the logs to. If relative, it will be appended to tmp. +- `run_on_start` (Boolean) This option defines whether or not the script should run when the agent starts. +- `run_on_stop` (Boolean) This option defines whether or not the script should run when the agent stops. +- `start_blocks_login` (Boolean) This option defines whether or not the user can (by default) login to the workspace before this script completes running on start. When enabled, users may see an incomplete workspace when logging in. +- `timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out, this happens when the script has not completed (exited) in the given time. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/provider/provider.go b/provider/provider.go index 32058b5b..9ea6685b 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -78,6 +78,7 @@ func New() *schema.Provider { "coder_agent_instance": agentInstanceResource(), "coder_app": appResource(), "coder_metadata": metadataResource(), + "coder_script": scriptResource(), }, } } diff --git a/provider/script.go b/provider/script.go new file mode 100644 index 00000000..fd02d4cc --- /dev/null +++ b/provider/script.go @@ -0,0 +1,91 @@ +package provider + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func scriptResource() *schema.Resource { + return &schema.Resource{ + Description: "Use this resource to run a script from an agent.", + CreateContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + rd.SetId(uuid.NewString()) + return nil + }, + ReadContext: schema.NoopContext, + DeleteContext: schema.NoopContext, + Schema: map[string]*schema.Schema{ + "agent_id": { + Type: schema.TypeString, + Description: `The "id" property of a "coder_agent" resource to associate with.`, + ForceNew: true, + Required: true, + }, + "display_name": { + Type: schema.TypeString, + Description: "The display name of the script to display logs in the dashboard.", + ForceNew: true, + Required: true, + }, + "log_path": { + Type: schema.TypeString, + Description: "The path of a file to write the logs to. If relative, it will be appended to tmp.", + ForceNew: true, + Optional: true, + }, + "icon": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Description: "A URL to an icon that will display in the dashboard. View built-in " + + "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + + "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + }, + "script": { + ForceNew: true, + Type: schema.TypeString, + Required: true, + Description: "The script to run.", + }, + "cron": { + ForceNew: true, + Type: schema.TypeString, + Optional: true, + Description: "The cron schedule to run the script on. This is a cron expression.", + }, + "start_blocks_login": { + Type: schema.TypeBool, + Default: false, + ForceNew: true, + Optional: true, + Description: "This option defines whether or not the user can (by default) login to the workspace before this script completes running on start. When enabled, users may see an incomplete workspace when logging in.", + }, + "run_on_start": { + Type: schema.TypeBool, + Default: false, + ForceNew: true, + Optional: true, + Description: "This option defines whether or not the script should run when the agent starts.", + }, + "run_on_stop": { + Type: schema.TypeBool, + Default: false, + ForceNew: true, + Optional: true, + Description: "This option defines whether or not the script should run when the agent stops.", + }, + "timeout": { + Type: schema.TypeInt, + Default: 0, + ForceNew: true, + Optional: true, + Description: "Time in seconds until the agent lifecycle status is marked as timed out, this happens when the script has not completed (exited) in the given time.", + ValidateFunc: validation.IntAtLeast(1), + }, + }, + } +} From ac4d723e52940938635889cf43c759c320dbc73a Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 13 Sep 2023 09:48:40 -0500 Subject: [PATCH 021/173] fix: add validation to cron (#159) --- go.mod | 1 + go.sum | 2 ++ provider/script.go | 15 +++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/go.mod b/go.mod index da846746..af666bdd 100644 --- a/go.mod +++ b/go.mod @@ -46,6 +46,7 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect diff --git a/go.sum b/go.sum index d98eda60..0ef602a8 100644 --- a/go.sum +++ b/go.sum @@ -143,6 +143,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= diff --git a/provider/script.go b/provider/script.go index fd02d4cc..8281d57d 100644 --- a/provider/script.go +++ b/provider/script.go @@ -2,13 +2,17 @@ package provider import ( "context" + "fmt" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/robfig/cron/v3" ) +var ScriptCRONParser = cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.DowOptional | cron.Descriptor) + func scriptResource() *schema.Resource { return &schema.Resource{ Description: "Use this resource to run a script from an agent.", @@ -56,6 +60,17 @@ func scriptResource() *schema.Resource { Type: schema.TypeString, Optional: true, Description: "The cron schedule to run the script on. This is a cron expression.", + ValidateFunc: func(i interface{}, s string) ([]string, []error) { + v, ok := i.(string) + if !ok { + return []string{}, []error{fmt.Errorf("got type %T instead of string", i)} + } + _, err := ScriptCRONParser.Parse(v) + if err != nil { + return []string{}, []error{fmt.Errorf("%s is not a valid cron expression: %w", v, err)} + } + return nil, nil + }, }, "start_blocks_login": { Type: schema.TypeBool, From 73943b25f818a1c9a12e3da15ecec8a21c813383 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 13 Sep 2023 15:31:44 -0500 Subject: [PATCH 022/173] feat: add template_id and template_name to workspace data source (#158) --- docs/data-sources/workspace.md | 2 ++ provider/workspace.go | 16 ++++++++++++++++ provider/workspace_test.go | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index c736f78a..4733edd4 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -36,4 +36,6 @@ resource "kubernetes_pod" "dev" { - `owner_oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. - `owner_session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. +- `template_id` (String) ID of the workspace's template. +- `template_name` (String) Name of the workspace's template. - `transition` (String) Either "start" or "stop". Use this to start/stop resources with "count". diff --git a/provider/workspace.go b/provider/workspace.go index 995cb6e4..a6ea64f6 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -60,6 +60,12 @@ func workspaceDataSource() *schema.Resource { } rd.SetId(id) + templateID := os.Getenv("CODER_WORKSPACE_TEMPLATE_ID") + _ = rd.Set("template_id", templateID) + + templateName := os.Getenv("CODER_WORKSPACE_TEMPLATE_NAME") + _ = rd.Set("template_name", templateName) + config, valid := i.(config) if !valid { return diag.Errorf("config was unexpected type %q", reflect.TypeOf(i).String()) @@ -139,6 +145,16 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started.", }, + "template_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the workspace's template.", + }, + "template_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the workspace's template.", + }, }, } } diff --git a/provider/workspace_test.go b/provider/workspace_test.go index 7662f4bc..69c64992 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -15,6 +15,8 @@ func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER", "owner123") t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") + t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") + t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ @@ -42,6 +44,8 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "owner123", attribs["owner"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) require.Equal(t, "abc123", attribs["owner_session_token"]) + require.Equal(t, "templateID", attribs["template_id"]) + require.Equal(t, "template123", attribs["template_name"]) return nil }, }}, @@ -71,6 +75,8 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "https://example.com:8080", attribs["access_url"]) require.Equal(t, "owner123", attribs["owner"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) + require.Equal(t, "templateID", attribs["template_id"]) + require.Equal(t, "template123", attribs["template_name"]) return nil }, }}, From a9ebf4bf70c7fd316e9038b26810cbd3bc2beaba Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Mon, 25 Sep 2023 18:20:13 -0500 Subject: [PATCH 023/173] fix: validate that `coder_script` has a way to run (#162) Previously, this would just silently push the script and it would never run, because it wasn't configured to do so. This changes it so all scripts have to be ran at some point. --- provider/script.go | 7 ++++ provider/script_test.go | 75 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 provider/script_test.go diff --git a/provider/script.go b/provider/script.go index 8281d57d..2db4829f 100644 --- a/provider/script.go +++ b/provider/script.go @@ -18,6 +18,13 @@ func scriptResource() *schema.Resource { Description: "Use this resource to run a script from an agent.", CreateContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) + runOnStart, _ := rd.Get("run_on_start").(bool) + runOnStop, _ := rd.Get("run_on_stop").(bool) + cron, _ := rd.Get("cron").(string) + + if !runOnStart && !runOnStop && cron == "" { + return diag.Errorf("at least one of run_on_start, run_on_stop, or cron must be set") + } return nil }, ReadContext: schema.NoopContext, diff --git a/provider/script_test.go b/provider/script_test.go new file mode 100644 index 00000000..4ecbacb6 --- /dev/null +++ b/provider/script_test.go @@ -0,0 +1,75 @@ +package provider_test + +import ( + "regexp" + "testing" + + "github.com/coder/terraform-provider-coder/provider" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestScript(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_script" "example" { + agent_id = "some id" + display_name = "Hey" + script = "Wow" + cron = "* * * * *" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_script.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "some id", + "display_name": "Hey", + "script": "Wow", + "cron": "* * * * *", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestScriptNeverRuns(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_script" "example" { + agent_id = "" + display_name = "Hey" + script = "Wow" + } + `, + ExpectError: regexp.MustCompile(`at least one of run_on_start, run_on_stop, or cron must be set`), + }}, + }) +} From c31c582dc779cd98e72674737792a3ed3012ac1c Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Tue, 3 Oct 2023 10:25:15 -0500 Subject: [PATCH 024/173] feat: add `coder_external_auth` and deprecate `coder_git_auth` (#163) * feat: add `coder_external_auth` and deprecate `coder_git_auth` * Improve docs --- docs/data-sources/external_auth.md | 24 ++++++++++++++++ provider/externalauth.go | 44 ++++++++++++++++++++++++++++++ provider/externalauth_test.go | 44 ++++++++++++++++++++++++++++++ provider/gitauth.go | 3 +- provider/provider.go | 9 +++--- 5 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 docs/data-sources/external_auth.md create mode 100644 provider/externalauth.go create mode 100644 provider/externalauth_test.go diff --git a/docs/data-sources/external_auth.md b/docs/data-sources/external_auth.md new file mode 100644 index 00000000..b875b874 --- /dev/null +++ b/docs/data-sources/external_auth.md @@ -0,0 +1,24 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_external_auth Data Source - terraform-provider-coder" +subcategory: "" +description: |- + Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc) +--- + +# coder_external_auth (Data Source) + +Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc) + + + + +## Schema + +### Required + +- `id` (String) The ID of a configured external auth provider set up in your Coder deployment. + +### Read-Only + +- `access_token` (String) The access token returned by the external auth provider. This can be used to pre-authenticate command-line tools. diff --git a/provider/externalauth.go b/provider/externalauth.go new file mode 100644 index 00000000..89ab5ecc --- /dev/null +++ b/provider/externalauth.go @@ -0,0 +1,44 @@ +package provider + +import ( + "context" + "fmt" + "os" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// externalAuthDataSource returns a schema for an external authentication data source. +func externalAuthDataSource() *schema.Resource { + return &schema.Resource{ + Description: "Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc)", + ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + id, ok := rd.Get("id").(string) + if !ok || id == "" { + return diag.Errorf("id is required") + } + rd.SetId(id) + + accessToken := os.Getenv(ExternalAuthAccessTokenEnvironmentVariable(id)) + rd.Set("access_token", accessToken) + return nil + }, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "The ID of a configured external auth provider set up in your Coder deployment.", + Required: true, + }, + "access_token": { + Type: schema.TypeString, + Computed: true, + Description: "The access token returned by the external auth provider. This can be used to pre-authenticate command-line tools.", + }, + }, + } +} + +func ExternalAuthAccessTokenEnvironmentVariable(id string) string { + return fmt.Sprintf("CODER_EXTERNAL_AUTH_ACCESS_TOKEN_%s", id) +} diff --git a/provider/externalauth_test.go b/provider/externalauth_test.go new file mode 100644 index 00000000..a320684b --- /dev/null +++ b/provider/externalauth_test.go @@ -0,0 +1,44 @@ +package provider_test + +import ( + "testing" + + "github.com/coder/terraform-provider-coder/provider" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/stretchr/testify/require" +) + +func TestExternalAuth(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + data "coder_external_auth" "github" { + id = "github" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_external_auth.github"] + require.NotNil(t, resource) + + attribs := resource.Primary.Attributes + require.Equal(t, "github", attribs["id"]) + + return nil + }, + }}, + }) +} diff --git a/provider/gitauth.go b/provider/gitauth.go index d5cf9a85..aa36d493 100644 --- a/provider/gitauth.go +++ b/provider/gitauth.go @@ -12,7 +12,8 @@ import ( // gitAuthDataSource returns a schema for a Git authentication data source. func gitAuthDataSource() *schema.Resource { return &schema.Resource{ - Description: "Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", + DeprecationMessage: "Use the `coder_external_auth` data source instead.", + Description: "Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rawID, ok := rd.GetOk("id") if !ok { diff --git a/provider/provider.go b/provider/provider.go index 9ea6685b..6556146e 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -68,10 +68,11 @@ func New() *schema.Provider { }, nil }, DataSourcesMap: map[string]*schema.Resource{ - "coder_workspace": workspaceDataSource(), - "coder_provisioner": provisionerDataSource(), - "coder_parameter": parameterDataSource(), - "coder_git_auth": gitAuthDataSource(), + "coder_workspace": workspaceDataSource(), + "coder_provisioner": provisionerDataSource(), + "coder_parameter": parameterDataSource(), + "coder_git_auth": gitAuthDataSource(), + "coder_external_auth": externalAuthDataSource(), }, ResourcesMap: map[string]*schema.Resource{ "coder_agent": agentResource(), From 095352f9db1171e3f9335a7f2f845bc98c522d78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:25:28 -0500 Subject: [PATCH 025/173] build(deps): Bump goreleaser/goreleaser-action from 4.3.0 to 5.0.0 (#156) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 4.3.0 to 5.0.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/v4.3.0...v5.0.0) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1b612b1..ec15cd28 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v4.3.0 + uses: goreleaser/goreleaser-action@v5.0.0 with: version: latest args: release --rm-dist From 5c3757f10ee403f32d41efbae6c918d3be4f2a9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:25:36 -0500 Subject: [PATCH 026/173] build(deps): Bump crazy-max/ghaction-import-gpg from 5.3.0 to 6.0.0 (#155) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 5.3.0 to 6.0.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v5.3.0...v6.0.0) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ec15cd28..fbfcb494 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5.3.0 + uses: crazy-max/ghaction-import-gpg@v6.0.0 with: # These secrets will need to be configured for the repository: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} From 108475a744880d7015ba2793810b17d0091b020c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:25:45 -0500 Subject: [PATCH 027/173] build(deps): Bump contributor-assistant/github-action (#160) Bumps [contributor-assistant/github-action](https://github.com/contributor-assistant/github-action) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/contributor-assistant/github-action/releases) - [Commits](https://github.com/contributor-assistant/github-action/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: contributor-assistant/github-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 51b35c7b..28b5e829 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.3.0 + uses: contributor-assistant/github-action@v2.3.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From bbea6b3fe7ef45a12271ab1fc69554463dcfcb99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:25:52 -0500 Subject: [PATCH 028/173] build(deps): Bump github.com/google/uuid from 1.3.0 to 1.3.1 (#148) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.0 to 1.3.1. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index af666bdd..983c1bdb 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/coder/terraform-provider-coder go 1.20 require ( - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index 0ef602a8..fe598df5 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= From a5ea15309def41c63316a3c0ace9fb2bd1437641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:20:49 -0500 Subject: [PATCH 029/173] build(deps): Bump actions/checkout from 3 to 4 (#151) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fbfcb494..530c3557 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Unshallow run: git fetch --prune --unshallow diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bdb30fe1..905b715d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: id: go - name: Check out code into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get dependencies run: | @@ -65,7 +65,7 @@ jobs: terraform_wrapper: false - name: Check out code into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get dependencies run: | @@ -95,7 +95,7 @@ jobs: terraform_wrapper: false - name: Check out code into the Go module directory - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get dependencies run: | From 70624be7f28ec0184461b921432a6a39e6920be9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:01:58 +0300 Subject: [PATCH 030/173] build(deps): Bump google.golang.org/grpc from 1.53.0 to 1.56.3 (#167) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.56.3. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.56.3) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 983c1bdb..b69665ae 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 + github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.8.4 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) @@ -17,7 +18,7 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect @@ -46,19 +47,18 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.3 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index fe598df5..04af201e 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -193,8 +193,8 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -215,15 +215,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= @@ -233,14 +233,14 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 4a5121af9ab56df25be22ad77f3862b688ea68da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:02:39 +0300 Subject: [PATCH 031/173] build(deps): Bump hashicorp/setup-terraform from 2 to 3 (#169) Bumps [hashicorp/setup-terraform](https://github.com/hashicorp/setup-terraform) from 2 to 3. - [Release notes](https://github.com/hashicorp/setup-terraform/releases) - [Changelog](https://github.com/hashicorp/setup-terraform/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/setup-terraform/compare/v2...v3) --- updated-dependencies: - dependency-name: hashicorp/setup-terraform dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 905b715d..fb9fd7c8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,7 +59,7 @@ jobs: go-version: "1.20" id: go - - uses: hashicorp/setup-terraform@v2 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: ${{ matrix.terraform }} terraform_wrapper: false @@ -89,7 +89,7 @@ jobs: go-version: "1.20" id: go - - uses: hashicorp/setup-terraform@v2 + - uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.3.*" terraform_wrapper: false From e6c53f1a29bd68848ead8b96587fd870e2daf8b9 Mon Sep 17 00:00:00 2001 From: Josh Vawdrey Date: Fri, 10 Nov 2023 19:03:31 +1100 Subject: [PATCH 032/173] feat(workspace): add the template version also (#166) * feat(workspace): add the template version also * Update workspace.md --- docs/data-sources/workspace.md | 1 + provider/workspace.go | 8 ++++++++ provider/workspace_test.go | 3 +++ 3 files changed, 12 insertions(+) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 4733edd4..5193dbe1 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -38,4 +38,5 @@ resource "kubernetes_pod" "dev" { - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. +- `template_version` (String) Version of the workspace's template. - `transition` (String) Either "start" or "stop". Use this to start/stop resources with "count". diff --git a/provider/workspace.go b/provider/workspace.go index a6ea64f6..4b1aa526 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -66,6 +66,9 @@ func workspaceDataSource() *schema.Resource { templateName := os.Getenv("CODER_WORKSPACE_TEMPLATE_NAME") _ = rd.Set("template_name", templateName) + templateVersion := os.Getenv("CODER_WORKSPACE_TEMPLATE_VERSION") + _ = rd.Set("template_version", templateVersion) + config, valid := i.(config) if !valid { return diag.Errorf("config was unexpected type %q", reflect.TypeOf(i).String()) @@ -155,6 +158,11 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Name of the workspace's template.", }, + "template_version": { + Type: schema.TypeString, + Computed: true, + Description: "Version of the workspace's template.", + }, }, } } diff --git a/provider/workspace_test.go b/provider/workspace_test.go index 69c64992..b40d86fe 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -17,6 +17,7 @@ func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") + t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ @@ -46,6 +47,7 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "abc123", attribs["owner_session_token"]) require.Equal(t, "templateID", attribs["template_id"]) require.Equal(t, "template123", attribs["template_name"]) + require.Equal(t, "v1.2.3", attribs["template_version"]) return nil }, }}, @@ -77,6 +79,7 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "owner123@example.com", attribs["owner_email"]) require.Equal(t, "templateID", attribs["template_id"]) require.Equal(t, "template123", attribs["template_name"]) + require.Equal(t, "v1.2.3", attribs["template_version"]) return nil }, }}, From 6b81e91b963ea4db0b598a5982008470ced885a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:04:39 +0300 Subject: [PATCH 033/173] build(deps): Bump github.com/google/uuid from 1.3.1 to 1.4.0 (#168) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.1 to 1.4.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b69665ae..501a6b6b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/coder/terraform-provider-coder go 1.20 require ( - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index 04af201e..8bcf588c 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= From 0040c1dabc38ccbdc66e6f02f5c66341e7a311f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:04:48 +0300 Subject: [PATCH 034/173] build(deps): Bump golang.org/x/net from 0.7.0 to 0.17.0 (#165) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.7.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 501a6b6b..03bf4ec1 100644 --- a/go.mod +++ b/go.mod @@ -52,10 +52,10 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect diff --git a/go.sum b/go.sum index 8bcf588c..52f7f7eb 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= -golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -193,8 +193,8 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -215,15 +215,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= From 7d258c1d6c77f4857e8df22e5f05a61d5d2302eb Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Wed, 22 Nov 2023 08:09:29 -0500 Subject: [PATCH 035/173] fix: add error detail for duplicate agent metadata key (#172) * fix: add error detail for duplicate agent metadata key * Update provider/agent.go Co-authored-by: Mathias Fredriksson --------- Co-authored-by: Mathias Fredriksson --- provider/agent.go | 14 ++++++++++++++ provider/agent_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/provider/agent.go b/provider/agent.go index 9b5ac3f3..4ba3f706 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "golang.org/x/xerrors" ) func agentResource() *schema.Resource { @@ -38,6 +39,19 @@ func agentResource() *schema.Resource { return diag.FromErr(err) } } + + rawPlan := resourceData.GetRawPlan() + items := rawPlan.GetAttr("metadata").AsValueSlice() + itemKeys := map[string]struct{}{} + for _, item := range items { + key := valueAsString(item.GetAttr("key")) + _, exists := itemKeys[key] + if exists { + return diag.FromErr(xerrors.Errorf("duplicate agent metadata key %q", key)) + } + itemKeys[key] = struct{}{} + } + return updateInitScript(resourceData, i) }, ReadWithoutTimeout: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { diff --git a/provider/agent_test.go b/provider/agent_test.go index 9026385c..a68b6580 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -250,6 +250,42 @@ func TestAgent_Metadata(t *testing.T) { }) } +func TestAgent_MetadataDuplicateKeys(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + metadata { + key = "process_count" + display_name = "Process Count" + script = "ps aux | wc -l" + interval = 5 + timeout = 1 + } + metadata { + key = "process_count" + display_name = "Process Count" + script = "ps aux | wc -l" + interval = 5 + timeout = 1 + } + } + `, + ExpectError: regexp.MustCompile("duplicate agent metadata key"), + }}, + }) +} + func TestAgent_DisplayApps(t *testing.T) { t.Parallel() t.Run("OK", func(t *testing.T) { From 39b0b24730cbba96ba8ca9971a66b09d505353e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 23:48:35 +0300 Subject: [PATCH 036/173] build(deps): Bump actions/setup-go from 4 to 5 (#173) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 530c3557..24e28a81 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: run: git fetch --prune --unshallow - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: 1.20.6 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fb9fd7c8..774dce94 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: timeout-minutes: 5 steps: - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.20" id: go @@ -54,7 +54,7 @@ jobs: - "1.5.*" steps: - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.20" id: go @@ -84,7 +84,7 @@ jobs: timeout-minutes: 5 steps: - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.20" id: go From 471368b686b4859224682ab03bb898f643e94e41 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 8 Dec 2023 16:10:49 +0200 Subject: [PATCH 037/173] feat: add `coder_env` (#174) Fixes #170 --- docs/resources/env.md | 29 ++++++++++ provider/env.go | 48 ++++++++++++++++ provider/env_test.go | 129 ++++++++++++++++++++++++++++++++++++++++++ provider/provider.go | 1 + 4 files changed, 207 insertions(+) create mode 100644 docs/resources/env.md create mode 100644 provider/env.go create mode 100644 provider/env_test.go diff --git a/docs/resources/env.md b/docs/resources/env.md new file mode 100644 index 00000000..5c68f08e --- /dev/null +++ b/docs/resources/env.md @@ -0,0 +1,29 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_env Resource - terraform-provider-coder" +subcategory: "" +description: |- + Use this resource to set an environment variable in a workspace. +--- + +# coder_env (Resource) + +Use this resource to set an environment variable in a workspace. + + + + +## Schema + +### Required + +- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `name` (String) The name of the environment variable. + +### Optional + +- `value` (String) The value of the environment variable. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/provider/env.go b/provider/env.go new file mode 100644 index 00000000..f71ae987 --- /dev/null +++ b/provider/env.go @@ -0,0 +1,48 @@ +package provider + +import ( + "context" + "regexp" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func envResource() *schema.Resource { + return &schema.Resource{ + Description: "Use this resource to set an environment variable in a workspace.", + CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { + rd.SetId(uuid.NewString()) + + return nil + }, + ReadContext: schema.NoopContext, + DeleteContext: schema.NoopContext, + Schema: map[string]*schema.Schema{ + "agent_id": { + Type: schema.TypeString, + Description: `The "id" property of a "coder_agent" resource to associate with.`, + ForceNew: true, + Required: true, + }, + "name": { + Type: schema.TypeString, + Description: "The name of the environment variable.", + ForceNew: true, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`), + "must be a valid environment variable name", + ), + }, + "value": { + Type: schema.TypeString, + Description: "The value of the environment variable.", + ForceNew: true, + Optional: true, + }, + }, + } +} diff --git a/provider/env_test.go b/provider/env_test.go new file mode 100644 index 00000000..66925f5e --- /dev/null +++ b/provider/env_test.go @@ -0,0 +1,129 @@ +package provider_test + +import ( + "regexp" + "testing" + + "github.com/coder/terraform-provider-coder/provider" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestEnv(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_env" "example" { + agent_id = "king" + name = "MESSAGE" + value = "Believe in yourself and there will come a day when others will have no choice but to believe with you." + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_env.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "name": "MESSAGE", + "value": "Believe in yourself and there will come a day when others will have no choice but to believe with you.", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestEnvEmptyValue(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_env" "example" { + agent_id = "king" + name = "MESSAGE" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_env.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "name": "MESSAGE", + "value": "", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestEnvBadName(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_env" "example" { + agent_id = "" + name = "bad-name" + } + `, + ExpectError: regexp.MustCompile(`must be a valid environment variable name`), + }}, + }) +} + +func TestEnvNoName(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_env" "example" { + agent_id = "" + } + `, + ExpectError: regexp.MustCompile(`The argument "name" is required, but no definition was found.`), + }}, + }) +} diff --git a/provider/provider.go b/provider/provider.go index 6556146e..fb262c8c 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -80,6 +80,7 @@ func New() *schema.Provider { "coder_app": appResource(), "coder_metadata": metadataResource(), "coder_script": scriptResource(), + "coder_env": envResource(), }, } } From bf903be8c104e9aeca76fa4977467c3cfce7d66b Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 8 Dec 2023 18:32:13 +0200 Subject: [PATCH 038/173] fix: improve docs for `coder_env` (#175) --- docs/resources/env.md | 4 ++-- provider/env.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/resources/env.md b/docs/resources/env.md index 5c68f08e..b948bad9 100644 --- a/docs/resources/env.md +++ b/docs/resources/env.md @@ -3,12 +3,12 @@ page_title: "coder_env Resource - terraform-provider-coder" subcategory: "" description: |- - Use this resource to set an environment variable in a workspace. + Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource. --- # coder_env (Resource) -Use this resource to set an environment variable in a workspace. +Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource. diff --git a/provider/env.go b/provider/env.go index f71ae987..66d03a22 100644 --- a/provider/env.go +++ b/provider/env.go @@ -12,7 +12,7 @@ import ( func envResource() *schema.Resource { return &schema.Resource{ - Description: "Use this resource to set an environment variable in a workspace.", + Description: `Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource.`, CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) From 9f85f76e400332c89a12da8d2699055896dc4096 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:08:42 +0000 Subject: [PATCH 039/173] build(deps): Bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#178) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 03bf4ec1..18efa326 100644 --- a/go.mod +++ b/go.mod @@ -52,10 +52,10 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect diff --git a/go.sum b/go.sum index 52f7f7eb..de3cbd9c 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -215,15 +215,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= From 8eb25b4e3acd62d639e129ae0d9b160a07b2158b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:08:54 +0000 Subject: [PATCH 040/173] build(deps): Bump github.com/google/uuid from 1.4.0 to 1.5.0 (#176) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 18efa326..dc085982 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/coder/terraform-provider-coder go 1.20 require ( - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index de3cbd9c..7a25c8ea 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= From 8785d492ec79fbf1c3e3f703ff872cd7202a787e Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 16 Jan 2024 13:06:47 +0100 Subject: [PATCH 041/173] feat: add to workspace (#181) --- docs/data-sources/workspace.md | 1 + provider/workspace.go | 8 ++++++++ provider/workspace_test.go | 3 +++ 3 files changed, 12 insertions(+) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 5193dbe1..f5b434a9 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -33,6 +33,7 @@ resource "kubernetes_pod" "dev" { - `owner` (String) Username of the workspace owner. - `owner_email` (String) Email address of the workspace owner. - `owner_id` (String) UUID of the workspace owner. +- `owner_name` (String) Name of the workspace owner. - `owner_oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. - `owner_session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. diff --git a/provider/workspace.go b/provider/workspace.go index 4b1aa526..be7bf03c 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -36,6 +36,9 @@ func workspaceDataSource() *schema.Resource { ownerEmail := os.Getenv("CODER_WORKSPACE_OWNER_EMAIL") _ = rd.Set("owner_email", ownerEmail) + ownerName := os.Getenv("CODER_WORKSPACE_OWNER_NAME") + _ = rd.Set("owner_name", ownerName) + ownerID := os.Getenv("CODER_WORKSPACE_OWNER_ID") if ownerID == "" { ownerID = uuid.Nil.String() @@ -126,6 +129,11 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "UUID of the workspace owner.", }, + "owner_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the workspace owner.", + }, "owner_oidc_access_token": { Type: schema.TypeString, Computed: true, diff --git a/provider/workspace_test.go b/provider/workspace_test.go index b40d86fe..38f9c743 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -13,6 +13,7 @@ import ( func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER", "owner123") + t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") @@ -43,6 +44,7 @@ func TestWorkspace(t *testing.T) { t.Log(value) require.Equal(t, "8080", attribs["access_port"]) require.Equal(t, "owner123", attribs["owner"]) + require.Equal(t, "Mr Owner", attribs["owner_name"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) require.Equal(t, "abc123", attribs["owner_session_token"]) require.Equal(t, "templateID", attribs["template_id"]) @@ -76,6 +78,7 @@ func TestWorkspace(t *testing.T) { t.Log(value) require.Equal(t, "https://example.com:8080", attribs["access_url"]) require.Equal(t, "owner123", attribs["owner"]) + require.Equal(t, "Mr Owner", attribs["owner_name"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) require.Equal(t, "templateID", attribs["template_id"]) require.Equal(t, "template123", attribs["template_name"]) From 4f8bd500d61c945b601525cc7d6d329be0a774bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 10:25:14 +0300 Subject: [PATCH 042/173] build(deps): Bump github.com/google/uuid from 1.5.0 to 1.6.0 (#182) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dc085982..2a99deb9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/coder/terraform-provider-coder go 1.20 require ( - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index 7a25c8ea..59028a90 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= From 56cf8457c70853a2d09298b117665971ee3331dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 10:26:11 +0300 Subject: [PATCH 043/173] build(deps): Bump crazy-max/ghaction-import-gpg from 6.0.0 to 6.1.0 (#179) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v6.0.0...v6.1.0) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24e28a81..0c21c4ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v6.0.0 + uses: crazy-max/ghaction-import-gpg@v6.1.0 with: # These secrets will need to be configured for the repository: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} From 7458fc08cb2f7fa84fe895f61c6b7900d16b3f85 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 7 Feb 2024 14:32:53 +0100 Subject: [PATCH 044/173] feat: add `order` property to agent_metadata (#187) --- docs/resources/agent.md | 18 ++++++++++++++++++ examples/resources/coder_agent/resource.tf | 17 +++++++++++++++++ provider/agent.go | 5 +++++ provider/agent_test.go | 2 ++ 4 files changed, 42 insertions(+) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 7e20ade4..d465c173 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -26,6 +26,23 @@ resource "coder_agent" "dev" { web_terminal = true ssh_helper = false } + + metadata { + display_name = "CPU Usage" + key = "cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + order = 2 + } + metadata { + display_name = "RAM Usage" + key = "ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + order = 1 + } } resource "kubernetes_pod" "dev" { @@ -97,4 +114,5 @@ Required: Optional: - `display_name` (String) The user-facing name of this value. +- `order` (Number) The order determines the position of agent metadata in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by key (ascending order). - `timeout` (Number) The maximum time the command is allowed to run in seconds. diff --git a/examples/resources/coder_agent/resource.tf b/examples/resources/coder_agent/resource.tf index d5235a18..0ed69ea3 100644 --- a/examples/resources/coder_agent/resource.tf +++ b/examples/resources/coder_agent/resource.tf @@ -11,6 +11,23 @@ resource "coder_agent" "dev" { web_terminal = true ssh_helper = false } + + metadata { + display_name = "CPU Usage" + key = "cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + order = 2 + } + metadata { + display_name = "RAM Usage" + key = "ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + order = 1 + } } resource "kubernetes_pod" "dev" { diff --git a/provider/agent.go b/provider/agent.go index 4ba3f706..cdeca50e 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -239,6 +239,11 @@ func agentResource() *schema.Resource { ForceNew: true, Required: true, }, + "order": { + Type: schema.TypeInt, + Optional: true, + Description: "The order determines the position of agent metadata in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by key (ascending order).", + }, }, }, }, diff --git a/provider/agent_test.go b/provider/agent_test.go index a68b6580..f70a7f90 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -225,6 +225,7 @@ func TestAgent_Metadata(t *testing.T) { script = "ps aux | wc -l" interval = 5 timeout = 1 + order = 7 } } `, @@ -244,6 +245,7 @@ func TestAgent_Metadata(t *testing.T) { require.Equal(t, "ps aux | wc -l", attr["metadata.0.script"]) require.Equal(t, "5", attr["metadata.0.interval"]) require.Equal(t, "1", attr["metadata.0.timeout"]) + require.Equal(t, "7", attr["metadata.0.order"]) return nil }, }}, From ec80a8ad19d589d1fa281a979fbd0218b377106a Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 8 Feb 2024 17:03:52 +0100 Subject: [PATCH 045/173] fix: metadata order with ForceNew (#189) --- provider/agent.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provider/agent.go b/provider/agent.go index cdeca50e..b814e15b 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -241,8 +241,9 @@ func agentResource() *schema.Resource { }, "order": { Type: schema.TypeInt, - Optional: true, Description: "The order determines the position of agent metadata in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by key (ascending order).", + ForceNew: true, + Optional: true, }, }, }, From e9d67f9a0bd9cf7e6a0ff5866109c5eaf2473ca7 Mon Sep 17 00:00:00 2001 From: Eric Paulsen Date: Thu, 8 Feb 2024 12:08:46 -0500 Subject: [PATCH 046/173] docs: deprecate startup_script_timeout & shutdown_script_timeout (#188) * docs: deprecate startup_script_timeout & shutdown_script_timeout * make: gen --- docs/resources/agent.md | 4 ++-- provider/agent.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index d465c173..8f96c852 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -78,10 +78,10 @@ resource "kubernetes_pod" "dev" { - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. -- `shutdown_script_timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. +- `shutdown_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. - `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. -- `startup_script_timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. +- `startup_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. ### Read-Only diff --git a/provider/agent.go b/provider/agent.go index b814e15b..c2bbfee3 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -131,6 +131,7 @@ func agentResource() *schema.Resource { ForceNew: true, Optional: true, Description: "Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time.", + Deprecated: "This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.", ValidateFunc: validation.IntAtLeast(1), }, "shutdown_script": { @@ -145,6 +146,7 @@ func agentResource() *schema.Resource { ForceNew: true, Optional: true, Description: "Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time.", + Deprecated: "This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.", ValidateFunc: validation.IntAtLeast(1), }, "token": { From 7a00ae7d9c2fc1f67b7bd7eb338c1d6bf3705af6 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Fri, 9 Feb 2024 11:19:29 +0100 Subject: [PATCH 047/173] feat: Add `order` to `coder_app` (#190) --- docs/resources/agent.md | 4 +++- docs/resources/app.md | 1 + examples/resources/coder_agent/resource.tf | 2 ++ provider/agent.go | 2 +- provider/app.go | 6 ++++++ provider/app_test.go | 2 ++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 8f96c852..9b07b2e7 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -43,6 +43,8 @@ resource "coder_agent" "dev" { timeout = 1 order = 1 } + + order = 1 } resource "kubernetes_pod" "dev" { @@ -114,5 +116,5 @@ Required: Optional: - `display_name` (String) The user-facing name of this value. -- `order` (Number) The order determines the position of agent metadata in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by key (ascending order). +- `order` (Number) The order determines the position of agent metadata in the UI presentation. The lowest order is shown first and metadata with equal order are sorted by key (ascending order). - `timeout` (Number) The maximum time the command is allowed to run in seconds. diff --git a/docs/resources/app.md b/docs/resources/app.md index 53a8c127..631eb1ec 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -73,6 +73,7 @@ resource "coder_app" "intellij" { - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `name` (String, Deprecated) A display name to identify the app. +- `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). - `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. - `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false. diff --git a/examples/resources/coder_agent/resource.tf b/examples/resources/coder_agent/resource.tf index 0ed69ea3..6ccb07bf 100644 --- a/examples/resources/coder_agent/resource.tf +++ b/examples/resources/coder_agent/resource.tf @@ -28,6 +28,8 @@ resource "coder_agent" "dev" { timeout = 1 order = 1 } + + order = 1 } resource "kubernetes_pod" "dev" { diff --git a/provider/agent.go b/provider/agent.go index c2bbfee3..a24f4c1b 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -243,7 +243,7 @@ func agentResource() *schema.Resource { }, "order": { Type: schema.TypeInt, - Description: "The order determines the position of agent metadata in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by key (ascending order).", + Description: "The order determines the position of agent metadata in the UI presentation. The lowest order is shown first and metadata with equal order are sorted by key (ascending order).", ForceNew: true, Optional: true, }, diff --git a/provider/app.go b/provider/app.go index d8471788..bd2eb21e 100644 --- a/provider/app.go +++ b/provider/app.go @@ -196,6 +196,12 @@ func appResource() *schema.Resource { }, }, }, + "order": { + Type: schema.TypeInt, + Description: "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order).", + ForceNew: true, + Optional: true, + }, }, } } diff --git a/provider/app_test.go b/provider/app_test.go index 3d4f44bb..f17513e1 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -44,6 +44,7 @@ func TestApp(t *testing.T) { interval = 5 threshold = 6 } + order = 4 } `, Check: func(state *terraform.State) error { @@ -64,6 +65,7 @@ func TestApp(t *testing.T) { "healthcheck.0.url", "healthcheck.0.interval", "healthcheck.0.threshold", + "order", } { value := resource.Primary.Attributes[key] t.Logf("%q = %q", key, value) From 908ab275adb67a340406c3981205e455ef8c62f7 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 9 Feb 2024 19:37:34 +0200 Subject: [PATCH 048/173] fix: improve coder_script related docs (#191) --- docs/resources/agent.md | 6 +++--- docs/resources/script.md | 10 +++++----- provider/agent.go | 8 ++++---- provider/script.go | 14 +++++++------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 9b07b2e7..23966105 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -79,10 +79,10 @@ resource "kubernetes_pod" "dev" { - `login_before_ready` (Boolean, Deprecated) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. -- `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. +- `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true. - `shutdown_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. -- `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. -- `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. +- `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true. +- `startup_script_behavior` (String) This option sets the behavior of the "startup_script". When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. This option is an alias for defining a "coder_script" resource with "start_blocks_login" set to true (blocking). - `startup_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. diff --git a/docs/resources/script.md b/docs/resources/script.md index 51213aac..a16b39f5 100644 --- a/docs/resources/script.md +++ b/docs/resources/script.md @@ -19,17 +19,17 @@ Use this resource to run a script from an agent. - `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. - `display_name` (String) The display name of the script to display logs in the dashboard. -- `script` (String) The script to run. +- `script` (String) The content of the script that will be run. ### Optional - `cron` (String) The cron schedule to run the script on. This is a cron expression. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `log_path` (String) The path of a file to write the logs to. If relative, it will be appended to tmp. -- `run_on_start` (Boolean) This option defines whether or not the script should run when the agent starts. -- `run_on_stop` (Boolean) This option defines whether or not the script should run when the agent stops. -- `start_blocks_login` (Boolean) This option defines whether or not the user can (by default) login to the workspace before this script completes running on start. When enabled, users may see an incomplete workspace when logging in. -- `timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out, this happens when the script has not completed (exited) in the given time. +- `run_on_start` (Boolean) This option defines whether or not the script should run when the agent starts. The script should exit when it is done to signal that the agent is ready. +- `run_on_stop` (Boolean) This option defines whether or not the script should run when the agent stops. The script should exit when it is done to signal that the workspace can be stopped. +- `start_blocks_login` (Boolean) This option determines whether users can log in immediately or must wait for the workspace to finish running this script upon startup. If not enabled, users may encounter an incomplete workspace when logging in. This option only sets the default, the user can still manually override the behavior. +- `timeout` (Number) Time in seconds that the script is allowed to run. If the script does not complete within this time, the script is terminated and the agent lifecycle status is marked as timed out. A value of zero (default) means no timeout. ### Read-Only diff --git a/provider/agent.go b/provider/agent.go index a24f4c1b..f02462a8 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -17,7 +17,7 @@ import ( func agentResource() *schema.Resource { return &schema.Resource{ Description: "Use this resource to associate an agent.", - CreateContext: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { + CreateContext: func(_ context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { // This should be a real authentication token! resourceData.SetId(uuid.NewString()) err := resourceData.Set("token", uuid.NewString()) @@ -121,7 +121,7 @@ func agentResource() *schema.Resource { }, "startup_script": { ForceNew: true, - Description: "A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready.", + Description: `A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true.`, Type: schema.TypeString, Optional: true, }, @@ -138,7 +138,7 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: "A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped.", + Description: `A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true.`, }, "shutdown_script_timeout": { Type: schema.TypeInt, @@ -197,7 +197,7 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: "This option sets the behavior of the `startup_script`. When set to \"blocking\", the startup_script must exit before the workspace is ready. When set to \"non-blocking\", the startup_script may run in the background and the workspace will be ready immediately. Default is \"non-blocking\", although \"blocking\" is recommended.", + Description: `This option sets the behavior of the "startup_script". When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. This option is an alias for defining a "coder_script" resource with "start_blocks_login" set to true (blocking).`, ValidateFunc: validation.StringInSlice([]string{"blocking", "non-blocking"}, false), ConflictsWith: []string{"login_before_ready"}, }, diff --git a/provider/script.go b/provider/script.go index 2db4829f..8b548a22 100644 --- a/provider/script.go +++ b/provider/script.go @@ -16,7 +16,7 @@ var ScriptCRONParser = cron.NewParser(cron.Second | cron.Minute | cron.Hour | cr func scriptResource() *schema.Resource { return &schema.Resource{ Description: "Use this resource to run a script from an agent.", - CreateContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) runOnStart, _ := rd.Get("run_on_start").(bool) runOnStop, _ := rd.Get("run_on_stop").(bool) @@ -60,14 +60,14 @@ func scriptResource() *schema.Resource { ForceNew: true, Type: schema.TypeString, Required: true, - Description: "The script to run.", + Description: "The content of the script that will be run.", }, "cron": { ForceNew: true, Type: schema.TypeString, Optional: true, Description: "The cron schedule to run the script on. This is a cron expression.", - ValidateFunc: func(i interface{}, s string) ([]string, []error) { + ValidateFunc: func(i interface{}, _ string) ([]string, []error) { v, ok := i.(string) if !ok { return []string{}, []error{fmt.Errorf("got type %T instead of string", i)} @@ -84,28 +84,28 @@ func scriptResource() *schema.Resource { Default: false, ForceNew: true, Optional: true, - Description: "This option defines whether or not the user can (by default) login to the workspace before this script completes running on start. When enabled, users may see an incomplete workspace when logging in.", + Description: "This option determines whether users can log in immediately or must wait for the workspace to finish running this script upon startup. If not enabled, users may encounter an incomplete workspace when logging in. This option only sets the default, the user can still manually override the behavior.", }, "run_on_start": { Type: schema.TypeBool, Default: false, ForceNew: true, Optional: true, - Description: "This option defines whether or not the script should run when the agent starts.", + Description: "This option defines whether or not the script should run when the agent starts. The script should exit when it is done to signal that the agent is ready.", }, "run_on_stop": { Type: schema.TypeBool, Default: false, ForceNew: true, Optional: true, - Description: "This option defines whether or not the script should run when the agent stops.", + Description: "This option defines whether or not the script should run when the agent stops. The script should exit when it is done to signal that the workspace can be stopped.", }, "timeout": { Type: schema.TypeInt, Default: 0, ForceNew: true, Optional: true, - Description: "Time in seconds until the agent lifecycle status is marked as timed out, this happens when the script has not completed (exited) in the given time.", + Description: "Time in seconds that the script is allowed to run. If the script does not complete within this time, the script is terminated and the agent lifecycle status is marked as timed out. A value of zero (default) means no timeout.", ValidateFunc: validation.IntAtLeast(1), }, }, From 1797a0306aef19c75ef14f1bafdef2cf123df207 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Fri, 9 Feb 2024 19:43:03 +0200 Subject: [PATCH 049/173] fix!: add extra validation for start_blocks_login (#192) --- provider/script.go | 4 +++ provider/script_test.go | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/provider/script.go b/provider/script.go index 8b548a22..4a05440e 100644 --- a/provider/script.go +++ b/provider/script.go @@ -19,12 +19,16 @@ func scriptResource() *schema.Resource { CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) runOnStart, _ := rd.Get("run_on_start").(bool) + startBlocksLogin, _ := rd.Get("start_blocks_login").(bool) runOnStop, _ := rd.Get("run_on_stop").(bool) cron, _ := rd.Get("cron").(string) if !runOnStart && !runOnStop && cron == "" { return diag.Errorf("at least one of run_on_start, run_on_stop, or cron must be set") } + if !runOnStart && startBlocksLogin { + return diag.Errorf("start_blocks_login can only be set if run_on_start is true") + } return nil }, ReadContext: schema.NoopContext, diff --git a/provider/script_test.go b/provider/script_test.go index 4ecbacb6..937c6008 100644 --- a/provider/script_test.go +++ b/provider/script_test.go @@ -73,3 +73,64 @@ func TestScriptNeverRuns(t *testing.T) { }}, }) } + +func TestScriptStartBlocksLoginRequiresRunOnStart(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_script" "example" { + agent_id = "" + display_name = "Hey" + script = "Wow" + run_on_stop = true + start_blocks_login = true + } + `, + ExpectError: regexp.MustCompile(`start_blocks_login can only be set if run_on_start is true`), + }}, + }) + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_script" "example" { + agent_id = "" + display_name = "Hey" + script = "Wow" + start_blocks_login = true + run_on_start = true + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_script.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "", + "display_name": "Hey", + "script": "Wow", + "start_blocks_login": "true", + "run_on_start": "true", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} From 99ba884053346eb75a5f5e662ee774b126c5dda9 Mon Sep 17 00:00:00 2001 From: Kayla Washburn-Love Date: Mon, 12 Feb 2024 15:46:35 -0700 Subject: [PATCH 050/173] feat: add `optional` property to `coder_external_auth` (#185) --- docs/data-sources/external_auth.md | 4 ++++ provider/externalauth.go | 7 +++++- provider/externalauth_test.go | 34 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/docs/data-sources/external_auth.md b/docs/data-sources/external_auth.md index b875b874..af4df43b 100644 --- a/docs/data-sources/external_auth.md +++ b/docs/data-sources/external_auth.md @@ -19,6 +19,10 @@ Use this data source to require users to authenticate with an external service p - `id` (String) The ID of a configured external auth provider set up in your Coder deployment. +### Optional + +- `optional` (Boolean) Authenticating with the external auth provider is not required, and can be skipped by users when creating or updating workspaces + ### Read-Only - `access_token` (String) The access token returned by the external auth provider. This can be used to pre-authenticate command-line tools. diff --git a/provider/externalauth.go b/provider/externalauth.go index 89ab5ecc..31dadd66 100644 --- a/provider/externalauth.go +++ b/provider/externalauth.go @@ -32,8 +32,13 @@ func externalAuthDataSource() *schema.Resource { }, "access_token": { Type: schema.TypeString, - Computed: true, Description: "The access token returned by the external auth provider. This can be used to pre-authenticate command-line tools.", + Computed: true, + }, + "optional": { + Type: schema.TypeBool, + Description: "Authenticating with the external auth provider is not required, and can be skipped by users when creating or updating workspaces", + Optional: true, }, }, } diff --git a/provider/externalauth_test.go b/provider/externalauth_test.go index a320684b..826f0a91 100644 --- a/provider/externalauth_test.go +++ b/provider/externalauth_test.go @@ -36,6 +36,40 @@ func TestExternalAuth(t *testing.T) { attribs := resource.Primary.Attributes require.Equal(t, "github", attribs["id"]) + require.Equal(t, "", attribs["optional"]) + + return nil + }, + }}, + }) +} + +func TestOptionalExternalAuth(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + data "coder_external_auth" "github" { + id = "github" + optional = true + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_external_auth.github"] + require.NotNil(t, resource) + + attribs := resource.Primary.Attributes + require.Equal(t, "github", attribs["id"]) + require.Equal(t, "true", attribs["optional"]) return nil }, From 7815596401d6e69aebb4ceefe1e84369cb63c4ac Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 13 Feb 2024 11:43:12 +0100 Subject: [PATCH 051/173] feat: Add `order` to `coder_agent` (#193) --- docs/resources/agent.md | 1 + provider/agent.go | 6 ++++++ provider/agent_test.go | 2 ++ 3 files changed, 9 insertions(+) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 23966105..68963947 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -79,6 +79,7 @@ resource "kubernetes_pod" "dev" { - `login_before_ready` (Boolean, Deprecated) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. +- `order` (Number) The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order). - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true. - `shutdown_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true. diff --git a/provider/agent.go b/provider/agent.go index f02462a8..7b197870 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -297,6 +297,12 @@ func agentResource() *schema.Resource { }, }, }, + "order": { + Type: schema.TypeInt, + Description: "The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order).", + ForceNew: true, + Optional: true, + }, }, } } diff --git a/provider/agent_test.go b/provider/agent_test.go index f70a7f90..491e59f9 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -39,6 +39,7 @@ func TestAgent(t *testing.T) { motd_file = "/etc/motd" shutdown_script = "echo bye bye" shutdown_script_timeout = 120 + order = 4 } `, Check: func(state *terraform.State) error { @@ -60,6 +61,7 @@ func TestAgent(t *testing.T) { "motd_file", "shutdown_script", "shutdown_script_timeout", + "order", } { value := resource.Primary.Attributes[key] t.Logf("%q = %q", key, value) From c18c9f158c7bd3b261684597093d8175efab5082 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 16 Feb 2024 19:15:48 +0300 Subject: [PATCH 052/173] chore: update description for `coder_app` `url` (#196) --- docs/resources/app.md | 2 +- provider/app.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resources/app.md b/docs/resources/app.md index 631eb1ec..56800b76 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -77,7 +77,7 @@ resource "coder_app" "intellij" { - `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. - `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false. -- `url` (String) A URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both. +- `url` (String) An external url if "external=true" or a URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both. ### Read-Only diff --git a/provider/app.go b/provider/app.go index bd2eb21e..ed0ac53e 100644 --- a/provider/app.go +++ b/provider/app.go @@ -150,7 +150,7 @@ func appResource() *schema.Resource { }, "url": { Type: schema.TypeString, - Description: "A URL to be proxied to from inside the workspace. " + + Description: "An external url if \"external=true\" or a URL to be proxied to from inside the workspace. " + "This should be of the form \"http://localhost:PORT[/SUBPATH]\". " + "Either \"command\" or \"url\" may be specified, but not both.", ForceNew: true, From 9c2e569e8e56e669061fbb80f1f7f79f3028edab Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 16 Feb 2024 19:27:24 +0300 Subject: [PATCH 053/173] ci: test for terraform version 1.6 and 1.7 (#197) --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 774dce94..5830a500 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,6 +52,8 @@ jobs: - "1.3.*" - "1.4.*" - "1.5.*" + - "1.6.*" + - "1.7.*" steps: - name: Set up Go uses: actions/setup-go@v5 From f5dc37cb863a6258016e10f3111611ca8b21181e Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 19 Feb 2024 16:33:49 +0100 Subject: [PATCH 054/173] feat: relax error message for number-typed coder parameters (#195) --- docs/data-sources/parameter.md | 2 +- provider/parameter.go | 34 +++++++++++++++++++++++++++------- provider/parameter_test.go | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index fc8100e7..4bded2d3 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -57,7 +57,7 @@ Optional: Optional: -- `error` (String) An error message to display if the value doesn't match the provided regex. +- `error` (String) An error message to display if the value breaks the validation rules. The following placeholders are supported: {max}, {min}, and {value}. - `max` (Number) The maximum of a number parameter. - `min` (Number) The minimum of a number parameter. - `monotonic` (String) Number monotonicity, either increasing or decreasing. diff --git a/provider/parameter.go b/provider/parameter.go index 339bb017..f4a31b7f 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -10,6 +10,7 @@ import ( "os" "regexp" "strconv" + "strings" "github.com/google/uuid" "github.com/hashicorp/go-cty/cty" @@ -314,10 +315,9 @@ func parameterDataSource() *schema.Resource { Optional: true, }, "error": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"validation.0.regex"}, - Description: "An error message to display if the value doesn't match the provided regex.", + Type: schema.TypeString, + Optional: true, + Description: "An error message to display if the value breaks the validation rules. The following placeholders are supported: {max}, {min}, and {value}.", }, }, }, @@ -438,13 +438,13 @@ func (v *Validation) Valid(typ, value string) error { case "number": num, err := strconv.Atoi(value) if err != nil { - return fmt.Errorf("value %q is not a number", value) + return takeFirstError(v.errorRendered(value), fmt.Errorf("value %q is not a number", value)) } if !v.MinDisabled && num < v.Min { - return fmt.Errorf("value %d is less than the minimum %d", num, v.Min) + return takeFirstError(v.errorRendered(value), fmt.Errorf("value %d is less than the minimum %d", num, v.Min)) } if !v.MaxDisabled && num > v.Max { - return fmt.Errorf("value %d is more than the maximum %d", num, v.Max) + return takeFirstError(v.errorRendered(value), fmt.Errorf("value %d is more than the maximum %d", num, v.Max)) } if v.Monotonic != "" && v.Monotonic != ValidationMonotonicIncreasing && v.Monotonic != ValidationMonotonicDecreasing { return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing) @@ -466,3 +466,23 @@ func ParameterEnvironmentVariable(name string) string { sum := sha256.Sum256([]byte(name)) return "CODER_PARAMETER_" + hex.EncodeToString(sum[:]) } + +func takeFirstError(errs ...error) error { + for _, err := range errs { + if err != nil { + return err + } + } + return xerrors.Errorf("developer error: error message is not provided") +} + +func (v *Validation) errorRendered(value string) error { + if v.Error == "" { + return nil + } + r := strings.NewReplacer( + "{min}", fmt.Sprintf("%d", v.Min), + "{max}", fmt.Sprintf("%d", v.Max), + "{value}", value) + return xerrors.Errorf(r.Replace(v.Error)) +} diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 48cf4829..e60c96f7 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -527,6 +527,20 @@ data "coder_parameter" "region" { } `, ExpectError: regexp.MustCompile("is more than the maximum"), + }, { + Name: "NumberValidation_CustomError", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 5 + validation { + max = 3 + error = "foobar" + } + } + `, + ExpectError: regexp.MustCompile("foobar"), }, { Name: "NumberValidation_NotInRange", Config: ` From ec5b604d1086a96b76f8e1541b9357c76aff0d85 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Fri, 22 Mar 2024 15:05:27 +0200 Subject: [PATCH 055/173] feat: allow `validation` to be used with `option`s (#202) --- README.md | 38 ++++++++++- .../resources/coder_parameter/resource.tf | 30 ++++++++ provider/parameter.go | 23 ++++--- provider/parameter_test.go | 68 ++++++++++++++++++- 4 files changed, 145 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cbec7099..151a7299 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ # terraform-provider-coder -See [Coder](https://github.com/coder/coder). +Terraform provider for [Coder](https://github.com/coder/coder). + +### Developing + +Follow the instructions outlined in the [Terraform documentation](https://developer.hashicorp.com/terraform/cli/config/config-file#development-overrides-for-provider-developers) +to setup your local Terraform to use your local version rather than the registry version. + +1. Create a file named `.terraformrc` in your `$HOME` directory +2. Add the following content: + ```hcl + provider_installation { + # Override the coder/coder provider to use your local version + dev_overrides { + "coder/coder" = "/path/to/terraform-provider-coder" + } + + # For all other providers, install them directly from their origin provider + # registries as normal. If you omit this, Terraform will _only_ use + # the dev_overrides block, and so no other providers will be available. + direct {} + } + ``` +3. (optional, but recommended) Validate your configuration: + 1. Create a new `main.tf` file and include: + ```hcl + terraform { + required_providers { + coder = { + source = "coder/coder" + } + } + } + ``` + 2. Run `terraform init` and observe a warning like `Warning: Provider development overrides are in effect` +4. Run `go build -o terraform-provider-coder` to build the provider binary, which Terraform will try locate and execute +5. All local Terraform runs will now use your local provider! +6. _**NOTE**: we vendor in this provider into `github.com/coder/coder`, so if you're testing with a local clone then you should also run `go mod edit -replace github.com/coder/terraform-provider-coder=/path/to/terraform-provider-coder` in your clone._ \ No newline at end of file diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index 3c674f1c..4efc3320 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -84,4 +84,34 @@ data "coder_parameter" "users" { display_name = "System users" type = "list(string)" default = jsonencode(["root", "user1", "user2"]) +} + +data "coder_parameter" "home_volume_size" { + name = "Home Volume Size" + description = <<-EOF + How large should your home volume be? + EOF + type = "number" + default = 30 + mutable = true + order = 3 + + option { + name = "30GB" + value = 30 + } + + option { + name = "60GB" + value = 60 + } + + option { + name = "100GB" + value = 100 + } + + validation { + monotonic = "increasing" + } } \ No newline at end of file diff --git a/provider/parameter.go b/provider/parameter.go index f4a31b7f..12dbc019 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -231,12 +231,11 @@ func parameterDataSource() *schema.Resource { }, }, "option": { - Type: schema.TypeList, - Description: "Each \"option\" block defines a value for a user to select from.", - ForceNew: true, - Optional: true, - MaxItems: 64, - ConflictsWith: []string{"validation"}, + Type: schema.TypeList, + Description: "Each \"option\" block defines a value for a user to select from.", + ForceNew: true, + Optional: true, + MaxItems: 64, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -276,11 +275,10 @@ func parameterDataSource() *schema.Resource { }, }, "validation": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Validate the input of a parameter.", - ConflictsWith: []string{"option"}, + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Description: "Validate the input of a parameter.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "min": { @@ -410,6 +408,9 @@ func (v *Validation) Valid(typ, value string) error { if !v.MaxDisabled { return fmt.Errorf("a max cannot be specified for a %s type", typ) } + if v.Monotonic != "" { + return fmt.Errorf("monotonic validation can only be specified for number types, not %s types", typ) + } } if typ != "string" && v.Regex != "" { return fmt.Errorf("a regex cannot be specified for a %s type", typ) diff --git a/provider/parameter_test.go b/provider/parameter_test.go index e60c96f7..05d3604b 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -73,7 +73,7 @@ func TestParameter(t *testing.T) { } }, }, { - Name: "ValidationWithOptions", + Name: "RegexValidationWithOptions", Config: ` data "coder_parameter" "region" { name = "Region" @@ -88,7 +88,23 @@ func TestParameter(t *testing.T) { } } `, - ExpectError: regexp.MustCompile("conflicts with option"), + ExpectError: regexp.MustCompile("a regex cannot be specified for a number type"), + }, { + Name: "MonotonicValidationWithNonNumberType", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + } + validation { + monotonic = "increasing" + } + } + `, + ExpectError: regexp.MustCompile("monotonic validation can only be specified for number types, not string types"), }, { Name: "ValidationRegexMissingError", Config: ` @@ -424,6 +440,54 @@ data "coder_parameter" "region" { require.Equal(t, expected, state.Primary.Attributes[key]) } }, + }, { + Name: "NumberValidation_MonotonicWithOptions", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "number" + description = <<-EOF + Always pick a larger region. + EOF + default = 1 + + option { + name = "Small" + value = 1 + } + + option { + name = "Medium" + value = 2 + } + + option { + name = "Large" + value = 3 + } + + validation { + monotonic = "increasing" + } + } + `, + Check: func(state *terraform.ResourceState) { + for key, expected := range map[string]any{ + "name": "Region", + "type": "number", + "validation.#": "1", + "option.0.name": "Small", + "option.0.value": "1", + "option.1.name": "Medium", + "option.1.value": "2", + "option.2.name": "Large", + "option.2.value": "3", + "default": "1", + "validation.0.monotonic": "increasing", + } { + require.Equal(t, expected, state.Primary.Attributes[key]) + } + }, }, { Name: "NumberValidation_Min", Config: ` From 176fb6a9f4329c1618b7424fdad7fa9792f1dab8 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Tue, 2 Apr 2024 19:01:40 -0400 Subject: [PATCH 056/173] feat: add owner group to workspace data (#204) --- docs/data-sources/workspace.md | 1 + provider/workspace.go | 17 +++++++++++++++++ provider/workspace_test.go | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index f5b434a9..2ed7c63d 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -32,6 +32,7 @@ resource "kubernetes_pod" "dev" { - `name` (String) Name of the workspace. - `owner` (String) Username of the workspace owner. - `owner_email` (String) Email address of the workspace owner. +- `owner_groups` (List of String) List of groups the workspace owner belongs to. - `owner_id` (String) UUID of the workspace owner. - `owner_name` (String) Name of the workspace owner. - `owner_oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. diff --git a/provider/workspace.go b/provider/workspace.go index be7bf03c..1511d2b5 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -2,6 +2,7 @@ package provider import ( "context" + "encoding/json" "os" "reflect" "strconv" @@ -36,6 +37,14 @@ func workspaceDataSource() *schema.Resource { ownerEmail := os.Getenv("CODER_WORKSPACE_OWNER_EMAIL") _ = rd.Set("owner_email", ownerEmail) + ownerGroupsText := os.Getenv("CODER_WORKSPACE_OWNER_GROUPS") + var ownerGroups []string + err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) + if err != nil { + return diag.Errorf("couldn't parse owner groups %q", ownerGroupsText) + } + _ = rd.Set("owner_groups", ownerGroups) + ownerName := os.Getenv("CODER_WORKSPACE_OWNER_NAME") _ = rd.Set("owner_name", ownerName) @@ -141,6 +150,14 @@ func workspaceDataSource() *schema.Resource { "This is only available if the workspace owner authenticated with OpenID Connect. " + "If a valid token cannot be obtained, this value will be an empty string.", }, + "owner_groups": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + Description: "List of groups the workspace owner belongs to.", + }, "id": { Type: schema.TypeString, Computed: true, diff --git a/provider/workspace_test.go b/provider/workspace_test.go index 38f9c743..78aeac4b 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -16,6 +16,7 @@ func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") + t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -47,6 +48,8 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "Mr Owner", attribs["owner_name"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) require.Equal(t, "abc123", attribs["owner_session_token"]) + require.Equal(t, "group1", attribs["owner_groups.0"]) + require.Equal(t, "group2", attribs["owner_groups.1"]) require.Equal(t, "templateID", attribs["template_id"]) require.Equal(t, "template123", attribs["template_name"]) require.Equal(t, "v1.2.3", attribs["template_version"]) @@ -80,6 +83,8 @@ func TestWorkspace(t *testing.T) { require.Equal(t, "owner123", attribs["owner"]) require.Equal(t, "Mr Owner", attribs["owner_name"]) require.Equal(t, "owner123@example.com", attribs["owner_email"]) + require.Equal(t, "group1", attribs["owner_groups.0"]) + require.Equal(t, "group2", attribs["owner_groups.1"]) require.Equal(t, "templateID", attribs["template_id"]) require.Equal(t, "template123", attribs["template_name"]) require.Equal(t, "v1.2.3", attribs["template_version"]) From ebce4cef4ec4324c021c096162249ad0397e47ab Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 3 Apr 2024 10:14:51 -0500 Subject: [PATCH 057/173] fix: check if owner groups exist before marshaling (#205) --- provider/workspace.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/provider/workspace.go b/provider/workspace.go index 1511d2b5..0e1abf97 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -39,9 +39,11 @@ func workspaceDataSource() *schema.Resource { ownerGroupsText := os.Getenv("CODER_WORKSPACE_OWNER_GROUPS") var ownerGroups []string - err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) - if err != nil { - return diag.Errorf("couldn't parse owner groups %q", ownerGroupsText) + if ownerGroupsText != "" { + err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) + if err != nil { + return diag.Errorf("couldn't parse owner groups %q", ownerGroupsText) + } } _ = rd.Set("owner_groups", ownerGroups) From d27a3b6f77c014706add893e53f91caced1dc334 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:50:46 -0500 Subject: [PATCH 058/173] build(deps): Bump contributor-assistant/github-action from 2.3.1 to 2.3.2 (#201) Bumps [contributor-assistant/github-action](https://github.com/contributor-assistant/github-action) from 2.3.1 to 2.3.2. - [Release notes](https://github.com/contributor-assistant/github-action/releases) - [Commits](https://github.com/contributor-assistant/github-action/compare/v2.3.1...v2.3.2) --- updated-dependencies: - dependency-name: contributor-assistant/github-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 28b5e829..db910ed8 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.3.1 + uses: contributor-assistant/github-action@v2.3.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From 9ae64fda47c11d10449bfdb126f55b92715cb8ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:51:06 -0500 Subject: [PATCH 059/173] build(deps): Bump google.golang.org/protobuf from 1.30.0 to 1.33.0 (#200) Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2a99deb9..ceee673d 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,6 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 59028a90..ecd9bb7e 100644 --- a/go.sum +++ b/go.sum @@ -239,8 +239,8 @@ google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From f3a205c94add5c861cb9ca3e4626560e786e38d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:51:25 -0500 Subject: [PATCH 060/173] build(deps): Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#199) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ceee673d..85e6c0ff 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index ecd9bb7e..fcd3ced0 100644 --- a/go.sum +++ b/go.sum @@ -160,8 +160,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= From b94b7ea775e25b570ce2ee37682f17115a9e3ffb Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 18 Apr 2024 11:28:14 +0100 Subject: [PATCH 061/173] fix(provider): coalesce arch to armv7 if on 32-bit arm (#210) This PR modifies the `coder_provisioner` datasource to return `arch` as `armv7` if `GOARCH=arm`. This fixes an issue where users on 32-bit arm platforms would be unable to create a template with ``` resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch ... } ``` and would instead need to manually specify ``` resource "coder_agent" "main" { arch = "armv7" ... } ``` --- docs/resources/agent_instance.md | 2 +- provider/provisioner.go | 4 ++++ provider/provisioner_test.go | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/resources/agent_instance.md b/docs/resources/agent_instance.md index fa8574fa..6af2bb46 100644 --- a/docs/resources/agent_instance.md +++ b/docs/resources/agent_instance.md @@ -3,7 +3,7 @@ page_title: "coder_agent_instance Resource - terraform-provider-coder" subcategory: "" description: |- - Use this resource to associate an instance ID with an agent for zero-trust authentication. This association is done automatically for "googlecomputeinstance", "awsinstance", "azurermlinuxvirtualmachine", and "azurermwindowsvirtual_machine" resources. + Use this resource to associate an instance ID with an agent for zero-trust authentication. This association is done automatically for "google_compute_instance", "aws_instance", "azurerm_linux_virtual_machine", and "azurerm_windows_virtual_machine" resources. --- # coder_agent_instance (Resource) diff --git a/provider/provisioner.go b/provider/provisioner.go index 49d8f401..314e89cd 100644 --- a/provider/provisioner.go +++ b/provider/provisioner.go @@ -16,6 +16,10 @@ func provisionerDataSource() *schema.Resource { rd.SetId(uuid.NewString()) rd.Set("os", runtime.GOOS) rd.Set("arch", runtime.GOARCH) + // Fix for #11782: if we're on 32-bit ARM, set arch to armv7. + if runtime.GOARCH == "arm" { + rd.Set("arch", "armv7") + } return nil }, diff --git a/provider/provisioner_test.go b/provider/provisioner_test.go index 777006f7..e9f83e43 100644 --- a/provider/provisioner_test.go +++ b/provider/provisioner_test.go @@ -31,9 +31,14 @@ func TestProvisioner(t *testing.T) { attribs := resource.Primary.Attributes require.Equal(t, runtime.GOOS, attribs["os"]) - require.Equal(t, runtime.GOARCH, attribs["arch"]) + if runtime.GOARCH == "arm" { + require.Equal(t, "armv7", attribs["arch"]) + } else { + require.Equal(t, runtime.GOARCH, attribs["arch"]) + } return nil }, }}, }) } + From 8c5e8ff9579d1d766d5317422bf3c1988b710434 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Tue, 23 Apr 2024 17:40:03 +0300 Subject: [PATCH 062/173] fix: set owner name and email to "default" (#209) --- provider/workspace.go | 6 ++++++ provider/workspace_test.go | 43 +++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/provider/workspace.go b/provider/workspace.go index 0e1abf97..b8ff1684 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -35,6 +35,9 @@ func workspaceDataSource() *schema.Resource { _ = rd.Set("owner", owner) ownerEmail := os.Getenv("CODER_WORKSPACE_OWNER_EMAIL") + if ownerEmail == "" { + ownerEmail = "default@example.com" + } _ = rd.Set("owner_email", ownerEmail) ownerGroupsText := os.Getenv("CODER_WORKSPACE_OWNER_GROUPS") @@ -48,6 +51,9 @@ func workspaceDataSource() *schema.Resource { _ = rd.Set("owner_groups", ownerGroups) ownerName := os.Getenv("CODER_WORKSPACE_OWNER_NAME") + if ownerName == "" { + ownerName = "default" + } _ = rd.Set("owner_name", ownerName) ownerID := os.Getenv("CODER_WORKSPACE_OWNER_ID") diff --git a/provider/workspace_test.go b/provider/workspace_test.go index 78aeac4b..d5866af5 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/coder/terraform-provider-coder/provider" @@ -43,20 +44,30 @@ func TestWorkspace(t *testing.T) { value := attribs["transition"] require.NotNil(t, value) t.Log(value) - require.Equal(t, "8080", attribs["access_port"]) - require.Equal(t, "owner123", attribs["owner"]) - require.Equal(t, "Mr Owner", attribs["owner_name"]) - require.Equal(t, "owner123@example.com", attribs["owner_email"]) - require.Equal(t, "abc123", attribs["owner_session_token"]) - require.Equal(t, "group1", attribs["owner_groups.0"]) - require.Equal(t, "group2", attribs["owner_groups.1"]) - require.Equal(t, "templateID", attribs["template_id"]) - require.Equal(t, "template123", attribs["template_name"]) - require.Equal(t, "v1.2.3", attribs["template_version"]) + assert.Equal(t, "https://example.com:8080", attribs["access_url"]) + assert.Equal(t, "8080", attribs["access_port"]) + assert.Equal(t, "owner123", attribs["owner"]) + assert.Equal(t, "Mr Owner", attribs["owner_name"]) + assert.Equal(t, "owner123@example.com", attribs["owner_email"]) + assert.Equal(t, "group1", attribs["owner_groups.0"]) + assert.Equal(t, "group2", attribs["owner_groups.1"]) + assert.Equal(t, "templateID", attribs["template_id"]) + assert.Equal(t, "template123", attribs["template_name"]) + assert.Equal(t, "v1.2.3", attribs["template_version"]) return nil }, }}, }) +} + +func TestWorkspace_UndefinedOwner(t *testing.T) { + t.Setenv("CODER_WORKSPACE_OWNER", "owner123") + t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") + t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) + t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") + t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") + t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") + resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ "coder": provider.New(), @@ -79,15 +90,9 @@ func TestWorkspace(t *testing.T) { value := attribs["transition"] require.NotNil(t, value) t.Log(value) - require.Equal(t, "https://example.com:8080", attribs["access_url"]) - require.Equal(t, "owner123", attribs["owner"]) - require.Equal(t, "Mr Owner", attribs["owner_name"]) - require.Equal(t, "owner123@example.com", attribs["owner_email"]) - require.Equal(t, "group1", attribs["owner_groups.0"]) - require.Equal(t, "group2", attribs["owner_groups.1"]) - require.Equal(t, "templateID", attribs["template_id"]) - require.Equal(t, "template123", attribs["template_name"]) - require.Equal(t, "v1.2.3", attribs["template_version"]) + assert.Equal(t, "owner123", attribs["owner"]) + assert.Equal(t, "default@example.com", attribs["owner_email"]) + // Skip other asserts return nil }, }}, From 204ea02a4356de982fa67186a2625500fe3bd55f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 09:19:13 +0100 Subject: [PATCH 063/173] build(deps): Bump golang.org/x/net from 0.17.0 to 0.23.0 (#211) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 85e6c0ff..7af7f224 100644 --- a/go.mod +++ b/go.mod @@ -52,9 +52,9 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/go.sum b/go.sum index fcd3ced0..93ed263d 100644 --- a/go.sum +++ b/go.sum @@ -181,8 +181,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -193,8 +193,8 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -215,8 +215,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= From 6d1b7363af798f3108e051aa5bc67f89aeef2094 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Mon, 29 Apr 2024 11:25:09 +0300 Subject: [PATCH 064/173] docs: remove jetbrains projector example from coder_app (#215) --- docs/resources/app.md | 8 -------- examples/resources/coder_app/resource.tf | 8 -------- 2 files changed, 16 deletions(-) diff --git a/docs/resources/app.md b/docs/resources/app.md index 56800b76..aec85255 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -47,14 +47,6 @@ resource "coder_app" "vim" { icon = "${data.coder_workspace.me.access_url}/icon/vim.svg" command = "vim" } - -resource "coder_app" "intellij" { - agent_id = coder_agent.dev.id - icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg" - slug = "intellij" - display_name = "JetBrains IntelliJ" - command = "projector run" -} ``` diff --git a/examples/resources/coder_app/resource.tf b/examples/resources/coder_app/resource.tf index 20fd8b41..9345dfc5 100644 --- a/examples/resources/coder_app/resource.tf +++ b/examples/resources/coder_app/resource.tf @@ -32,11 +32,3 @@ resource "coder_app" "vim" { icon = "${data.coder_workspace.me.access_url}/icon/vim.svg" command = "vim" } - -resource "coder_app" "intellij" { - agent_id = coder_agent.dev.id - icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg" - slug = "intellij" - display_name = "JetBrains IntelliJ" - command = "projector run" -} From 3cc9802d8c2ac8a6254b1c7242fbc9e19756bc46 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Tue, 30 Apr 2024 05:58:43 +0300 Subject: [PATCH 065/173] chore: add a minimal nix flake (#216) --- README.md | 11 ++++++++++ flake.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 29 ++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/README.md b/README.md index 151a7299..d4b48fac 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,17 @@ Terraform provider for [Coder](https://github.com/coder/coder). ### Developing +#### Prerequisites + +- [Go](https://golang.org/doc/install) +- [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) + +We recommend using [`nix`](https://nixos.org/download.html) to manage your development environment. If you have `nix` installed, you can run `nix develop` to enter a shell with all the necessary dependencies. + +Alternatively, you can install the dependencies manually. + +#### Building + Follow the instructions outlined in the [Terraform documentation](https://developer.hashicorp.com/terraform/cli/config/config-file#development-overrides-for-provider-developers) to setup your local Terraform to use your local version rather than the registry version. diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..d8033e14 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1714272655, + "narHash": "sha256-3/ghIWCve93ngkx5eNPdHIKJP/pMzSr5Wc4rNKE1wOc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "12430e43bd9b81a6b4e79e64f87c624ade701eaf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..87719bf4 --- /dev/null +++ b/flake.nix @@ -0,0 +1,29 @@ +{ + description = "Terraform provider for Coder"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + config = { + allowUnfree = true; + }; + }; + in + { + devShell = pkgs.mkShell { + name = "devShell"; + buildInputs = with pkgs; [ + terraform + go_1_20 + ]; + }; + } + ); +} From 8fa0fbf8655a58e973a93bbe2e69bb86bca3bb55 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Mon, 13 May 2024 11:06:48 -0400 Subject: [PATCH 066/173] fix: add test case to validate empty provider (#206) --- provider/provider_test.go | 34 ++++++++++++++++++++++++++++++++++ provider/provisioner_test.go | 1 + 2 files changed, 35 insertions(+) diff --git a/provider/provider_test.go b/provider/provider_test.go index cd00f9a4..c1e3c686 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -3,6 +3,9 @@ package provider_test import ( "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" "github.com/coder/terraform-provider-coder/provider" @@ -14,3 +17,34 @@ func TestProvider(t *testing.T) { err := tfProvider.InternalValidate() require.NoError(t, err) } + +// TestProviderEmpty ensures that the provider can be configured without +// any actual input data. This is important for adding new fields +// with backwards compatibility guarantees. +func TestProviderEmpty(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" {} + data "coder_provisioner" "me" {} + data "coder_workspace" "me" {} + data "coder_external_auth" "git" { + id = "git" + } + data "coder_git_auth" "git" { + id = "git" + } + data "coder_parameter" "param" { + name = "hey" + }`, + Check: func(state *terraform.State) error { + return nil + }, + }}, + }) +} diff --git a/provider/provisioner_test.go b/provider/provisioner_test.go index e9f83e43..f1521ef9 100644 --- a/provider/provisioner_test.go +++ b/provider/provisioner_test.go @@ -12,6 +12,7 @@ import ( ) func TestProvisioner(t *testing.T) { + t.Parallel() resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ "coder": provider.New(), From 041e000b50a7b697db9d58d9cfc08c6ef5f3b9af Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 16 May 2024 17:29:09 +0200 Subject: [PATCH 067/173] feat: support workspace tags (#223) --- .../coder_workspace_tags/resource.tf | 50 +++++++++++++++++++ provider/examples_test.go | 28 +++++++---- provider/provider.go | 11 ++-- provider/workspace_tags.go | 32 ++++++++++++ provider/workspace_tags_test.go | 48 ++++++++++++++++++ 5 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 examples/resources/coder_workspace_tags/resource.tf create mode 100644 provider/workspace_tags.go create mode 100644 provider/workspace_tags_test.go diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/resources/coder_workspace_tags/resource.tf new file mode 100644 index 00000000..6c26b061 --- /dev/null +++ b/examples/resources/coder_workspace_tags/resource.tf @@ -0,0 +1,50 @@ +provider "coder" {} + +data "coder_parameter" "os_selector" { + name = "os_selector" + display_name = "Operating System" + mutable = false + + default = "osx" + + option { + icon = "/icons/linux.png" + name = "Linux" + value = "linux" + } + option { + icon = "/icons/osx.png" + name = "OSX" + value = "osx" + } + option { + icon = "/icons/windows.png" + name = "Windows" + value = "windows" + } +} + +data "coder_parameter" "feature_cache_enabled" { + name = "feature_cache_enabled" + display_name = "Enable cache?" + type = "bool" + + default = false +} + +data "coder_parameter" "feature_debug_enabled" { + name = "feature_debug_enabled" + display_name = "Enable debug?" + type = "bool" + + default = true +} + +data "coder_workspace_tags" "custom_workspace_tags" { + tags = { + "cluster" = "developers" + "os" = data.coder_parameter.os_selector.value + "debug" = "${data.coder_parameter.feature_debug_enabled.value}+12345" + "cache" = data.coder_parameter.feature_cache_enabled.value == "true" ? "nix-with-cache" : "no-cache" + } +} \ No newline at end of file diff --git a/provider/examples_test.go b/provider/examples_test.go index 9be7ce02..6fa73d21 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -14,19 +14,25 @@ import ( func TestExamples(t *testing.T) { t.Parallel() - t.Run("coder_parameter", func(t *testing.T) { - t.Parallel() + for _, testDir := range []string{ + "coder_parameter", + "coder_workspace_tags", + } { + t.Run(testDir, func(t *testing.T) { + testDir := testDir + t.Parallel() - resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, - Steps: []resource.TestStep{{ - Config: mustReadFile(t, "../examples/resources/coder_parameter/resource.tf"), - }}, + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: mustReadFile(t, "../examples/resources/"+testDir+"/resource.tf"), + }}, + }) }) - }) + } } func mustReadFile(t *testing.T, path string) string { diff --git a/provider/provider.go b/provider/provider.go index fb262c8c..4ea75ba8 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -68,11 +68,12 @@ func New() *schema.Provider { }, nil }, DataSourcesMap: map[string]*schema.Resource{ - "coder_workspace": workspaceDataSource(), - "coder_provisioner": provisionerDataSource(), - "coder_parameter": parameterDataSource(), - "coder_git_auth": gitAuthDataSource(), - "coder_external_auth": externalAuthDataSource(), + "coder_workspace": workspaceDataSource(), + "coder_workspace_tags": workspaceTagDataSource(), + "coder_provisioner": provisionerDataSource(), + "coder_parameter": parameterDataSource(), + "coder_git_auth": gitAuthDataSource(), + "coder_external_auth": externalAuthDataSource(), }, ResourcesMap: map[string]*schema.Resource{ "coder_agent": agentResource(), diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go new file mode 100644 index 00000000..088ff546 --- /dev/null +++ b/provider/workspace_tags.go @@ -0,0 +1,32 @@ +package provider + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +type WorkspaceTags struct { + Tags map[string]string +} + +func workspaceTagDataSource() *schema.Resource { + return &schema.Resource{ + Description: "Use this data source to configure workspace tags to select provisioners.", + ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + rd.SetId(uuid.NewString()) + return nil + }, + Schema: map[string]*schema.Schema{ + "tags": { + Type: schema.TypeMap, + Description: `Key-value map with workspace tags`, + ForceNew: true, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} diff --git a/provider/workspace_tags_test.go b/provider/workspace_tags_test.go new file mode 100644 index 00000000..2d0f1c49 --- /dev/null +++ b/provider/workspace_tags_test.go @@ -0,0 +1,48 @@ +package provider_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/require" + + "github.com/coder/terraform-provider-coder/provider" +) + +func TestWorkspaceTags(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + data "coder_parameter" "animal" { + name = "animal" + type = "string" + default = "chris" + } + data "coder_workspace_tags" "wt" { + tags = { + "cat" = "james" + "dog" = data.coder_parameter.animal.value + } + }`, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 2) + resource := state.Modules[0].Resources["data.coder_workspace_tags.wt"] + require.NotNil(t, resource) + + attribs := resource.Primary.Attributes + require.Equal(t, "james", attribs["tags.cat"]) + require.Equal(t, "chris", attribs["tags.dog"]) + return nil + }, + }}, + }) +} From 4f9201481404d78754711bc5fb1982d56a869e4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 May 2024 16:05:51 +0300 Subject: [PATCH 068/173] build(deps): Bump contributor-assistant/github-action from 2.3.2 to 2.4.0 (#221) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index db910ed8..412cac6b 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.3.2 + uses: contributor-assistant/github-action@v2.4.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From d921c8319d4d9108489bde8703d3fc5425923052 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 12:20:00 +0300 Subject: [PATCH 069/173] build(deps): Bump goreleaser/goreleaser-action from 5.0.0 to 5.1.0 (#225) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c21c4ac..00fd83ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5.0.0 + uses: goreleaser/goreleaser-action@v5.1.0 with: version: latest args: release --rm-dist From 2642fa5e14d1a0bf87b9ce4abc4a4db5f209d307 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 23 May 2024 12:45:44 +0100 Subject: [PATCH 070/173] chore: add devcontainer config (#228) --- .devcontainer/devcontainer.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fa152f4d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,9 @@ +{ + "name": "terraform-provider-coder", + "image": "mcr.microsoft.com/devcontainers/go:1.20", + "features": { + "ghcr.io/devcontainers/features/terraform:1": { + "installTerraformDocs": true + } + } +} From c683ad5b3888469cc26d625b6c890f70a022a024 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 23 May 2024 12:45:53 +0100 Subject: [PATCH 071/173] chore: add terraform 1.8.x to test matrix (#229) --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5830a500..fefaf2f5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,6 +54,7 @@ jobs: - "1.5.*" - "1.6.*" - "1.7.*" + - "1.8.*" steps: - name: Set up Go uses: actions/setup-go@v5 From 7e5a28b99dfea0f40526b0bedd61aac39c1b3d9e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 24 May 2024 14:45:08 +0100 Subject: [PATCH 072/173] chore: make gen to add missing docs (#231) --- docs/data-sources/workspace_tags.md | 24 +++++++++++++++++++ docs/resources/metadata.md | 7 ++++++ examples/resources/coder_metadata/resource.tf | 7 ++++++ 3 files changed, 38 insertions(+) create mode 100644 docs/data-sources/workspace_tags.md diff --git a/docs/data-sources/workspace_tags.md b/docs/data-sources/workspace_tags.md new file mode 100644 index 00000000..62f72b0f --- /dev/null +++ b/docs/data-sources/workspace_tags.md @@ -0,0 +1,24 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_workspace_tags Data Source - terraform-provider-coder" +subcategory: "" +description: |- + Use this data source to configure workspace tags to select provisioners. +--- + +# coder_workspace_tags (Data Source) + +Use this data source to configure workspace tags to select provisioners. + + + + +## Schema + +### Optional + +- `tags` (Map of String) Key-value map with workspace tags + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/docs/resources/metadata.md b/docs/resources/metadata.md index 2d67e526..9d6ff92f 100644 --- a/docs/resources/metadata.md +++ b/docs/resources/metadata.md @@ -18,6 +18,13 @@ data "coder_workspace" "me" { resource "kubernetes_pod" "dev" { count = data.coder_workspace.me.start_count + metadata { + name = "k8s_example" + namespace = "example" + } + spec { + # Draw the rest of the pod! + } } resource "tls_private_key" "example_key_pair" { diff --git a/examples/resources/coder_metadata/resource.tf b/examples/resources/coder_metadata/resource.tf index c4facfbb..0491ce57 100644 --- a/examples/resources/coder_metadata/resource.tf +++ b/examples/resources/coder_metadata/resource.tf @@ -3,6 +3,13 @@ data "coder_workspace" "me" { resource "kubernetes_pod" "dev" { count = data.coder_workspace.me.start_count + metadata { + name = "k8s_example" + namespace = "example" + } + spec { + # Draw the rest of the pod! + } } resource "tls_private_key" "example_key_pair" { From eb43b9f95bbbb54af72496b3a72f05c6dfffacbf Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 24 May 2024 14:48:20 +0100 Subject: [PATCH 073/173] feat: add coder_workspace_owner datasource (#230) - Adds a coder_workspace_owner data source populated from fields of coder_workspace prefix with `owner_`. - Adds `coder_workspace_owner.ssh_{public,private}_key`. - Deprecates same fields of coder_workspace. --- docs/data-sources/workspace.md | 14 +-- docs/data-sources/workspace_owner.md | 28 ++++++ provider/provider.go | 13 +-- provider/workspace.go | 7 ++ provider/workspace_owner.go | 127 +++++++++++++++++++++++++++ provider/workspace_owner_test.go | 119 +++++++++++++++++++++++++ provider/workspace_test.go | 4 + 7 files changed, 299 insertions(+), 13 deletions(-) create mode 100644 docs/data-sources/workspace_owner.md create mode 100644 provider/workspace_owner.go create mode 100644 provider/workspace_owner_test.go diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 2ed7c63d..2a813722 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -30,13 +30,13 @@ resource "kubernetes_pod" "dev" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `name` (String) Name of the workspace. -- `owner` (String) Username of the workspace owner. -- `owner_email` (String) Email address of the workspace owner. -- `owner_groups` (List of String) List of groups the workspace owner belongs to. -- `owner_id` (String) UUID of the workspace owner. -- `owner_name` (String) Name of the workspace owner. -- `owner_oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. +- `owner` (String, Deprecated) Username of the workspace owner. +- `owner_email` (String, Deprecated) Email address of the workspace owner. +- `owner_groups` (List of String, Deprecated) List of groups the workspace owner belongs to. +- `owner_id` (String, Deprecated) UUID of the workspace owner. +- `owner_name` (String, Deprecated) Name of the workspace owner. +- `owner_oidc_access_token` (String, Deprecated) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. +- `owner_session_token` (String, Deprecated) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md new file mode 100644 index 00000000..646b1340 --- /dev/null +++ b/docs/data-sources/workspace_owner.md @@ -0,0 +1,28 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_workspace_owner Data Source - terraform-provider-coder" +subcategory: "" +description: |- + Use this data source to fetch information about the workspace owner. +--- + +# coder_workspace_owner (Data Source) + +Use this data source to fetch information about the workspace owner. + + + + +## Schema + +### Read-Only + +- `email` (String) The email address of the user. +- `full_name` (String) The full name of the user. +- `groups` (List of String) The groups of which the user is a member. +- `id` (String) The UUID of the workspace owner. +- `name` (String) The username of the user. +- `oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. +- `session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated every time a workspace is started. +- `ssh_private_key` (String, Sensitive) The user's generated SSH private key. +- `ssh_public_key` (String) The user's generated SSH public key. diff --git a/provider/provider.go b/provider/provider.go index 4ea75ba8..c1991a26 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -68,12 +68,13 @@ func New() *schema.Provider { }, nil }, DataSourcesMap: map[string]*schema.Resource{ - "coder_workspace": workspaceDataSource(), - "coder_workspace_tags": workspaceTagDataSource(), - "coder_provisioner": provisionerDataSource(), - "coder_parameter": parameterDataSource(), - "coder_git_auth": gitAuthDataSource(), - "coder_external_auth": externalAuthDataSource(), + "coder_workspace": workspaceDataSource(), + "coder_workspace_tags": workspaceTagDataSource(), + "coder_provisioner": provisionerDataSource(), + "coder_parameter": parameterDataSource(), + "coder_git_auth": gitAuthDataSource(), + "coder_external_auth": externalAuthDataSource(), + "coder_workspace_owner": workspaceOwnerDataSource(), }, ResourcesMap: map[string]*schema.Resource{ "coder_agent": agentResource(), diff --git a/provider/workspace.go b/provider/workspace.go index b8ff1684..098d64cc 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -135,21 +135,25 @@ func workspaceDataSource() *schema.Resource { Type: schema.TypeString, Computed: true, Description: "Username of the workspace owner.", + Deprecated: "Use `coder_workspace_owner.name` instead.", }, "owner_email": { Type: schema.TypeString, Computed: true, Description: "Email address of the workspace owner.", + Deprecated: "Use `coder_workspace_owner.email` instead.", }, "owner_id": { Type: schema.TypeString, Computed: true, Description: "UUID of the workspace owner.", + Deprecated: "Use `coder_workspace_owner.id` instead.", }, "owner_name": { Type: schema.TypeString, Computed: true, Description: "Name of the workspace owner.", + Deprecated: "Use `coder_workspace_owner.full_name` instead.", }, "owner_oidc_access_token": { Type: schema.TypeString, @@ -157,6 +161,7 @@ func workspaceDataSource() *schema.Resource { Description: "A valid OpenID Connect access token of the workspace owner. " + "This is only available if the workspace owner authenticated with OpenID Connect. " + "If a valid token cannot be obtained, this value will be an empty string.", + Deprecated: "Use `coder_workspace_owner.oidc_access_token` instead.", }, "owner_groups": { Type: schema.TypeList, @@ -165,6 +170,7 @@ func workspaceDataSource() *schema.Resource { }, Computed: true, Description: "List of groups the workspace owner belongs to.", + Deprecated: "Use `coder_workspace_owner.groups` instead.", }, "id": { Type: schema.TypeString, @@ -180,6 +186,7 @@ func workspaceDataSource() *schema.Resource { Type: schema.TypeString, Computed: true, Description: "Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started.", + Deprecated: "Use `coder_workspace_owner.session_token` instead.", }, "template_id": { Type: schema.TypeString, diff --git a/provider/workspace_owner.go b/provider/workspace_owner.go new file mode 100644 index 00000000..5721b5c5 --- /dev/null +++ b/provider/workspace_owner.go @@ -0,0 +1,127 @@ +package provider + +import ( + "context" + "encoding/json" + "os" + "strings" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +type Role struct { + Name string `json:"name"` + DisplayName string `json:"display-name"` +} + +func workspaceOwnerDataSource() *schema.Resource { + return &schema.Resource{ + Description: "Use this data source to fetch information about the workspace owner.", + ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + if idStr, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_ID"); ok { + rd.SetId(idStr) + } else { + rd.SetId(uuid.NewString()) + } + + if username, ok := os.LookupEnv("CODER_WORKSPACE_OWNER"); ok { + _ = rd.Set("name", username) + } else { + _ = rd.Set("name", "default") + } + + if fullname, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_NAME"); ok { + _ = rd.Set("full_name", fullname) + } else { // compat: field can be blank, fill in default + _ = rd.Set("full_name", "default") + } + + if email, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_EMAIL"); ok { + _ = rd.Set("email", email) + } else { + _ = rd.Set("email", "default@example.com") + } + + if sshPubKey, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY"); ok { + _ = rd.Set("ssh_public_key", sshPubKey) + } + + if sshPrivKey, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY"); ok { + _ = rd.Set("ssh_private_key", sshPrivKey) + } + + var groups []string + if groupsRaw, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_GROUPS"); ok { + if err := json.NewDecoder(strings.NewReader(groupsRaw)).Decode(&groups); err != nil { + return diag.Errorf("invalid user groups: %s", err.Error()) + } + _ = rd.Set("groups", groups) + } + + if tok, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SESSION_TOKEN"); ok { + _ = rd.Set("session_token", tok) + } + + if tok, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN"); ok { + _ = rd.Set("oidc_access_token", tok) + } + + return nil + }, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The UUID of the workspace owner.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The username of the user.", + }, + "full_name": { + Type: schema.TypeString, + Computed: true, + Description: "The full name of the user.", + }, + "email": { + Type: schema.TypeString, + Computed: true, + Description: "The email address of the user.", + }, + "ssh_public_key": { + Type: schema.TypeString, + Computed: true, + Description: "The user's generated SSH public key.", + }, + "ssh_private_key": { + Type: schema.TypeString, + Computed: true, + Description: "The user's generated SSH private key.", + Sensitive: true, + }, + "groups": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + Description: "The groups of which the user is a member.", + }, + "session_token": { + Type: schema.TypeString, + Computed: true, + Description: "Session token for authenticating with a Coder deployment. It is regenerated every time a workspace is started.", + }, + "oidc_access_token": { + Type: schema.TypeString, + Computed: true, + Description: "A valid OpenID Connect access token of the workspace owner. " + + "This is only available if the workspace owner authenticated with OpenID Connect. " + + "If a valid token cannot be obtained, this value will be an empty string.", + }, + }, + } +} diff --git a/provider/workspace_owner_test.go b/provider/workspace_owner_test.go new file mode 100644 index 00000000..90839cfc --- /dev/null +++ b/provider/workspace_owner_test.go @@ -0,0 +1,119 @@ +package provider_test + +import ( + "os" + "testing" + + "github.com/coder/terraform-provider-coder/provider" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + testSSHEd25519PublicKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJeNcdBMtd4Jo9f2W8RZef0ld7Ypye5zTQEf0vUXa/Eq owner123@host456` + // nolint:gosec // This key was generated specifically for this purpose. + testSSHEd25519PrivateKey = `-----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW + QyNTUxOQAAACCXjXHQTLXeCaPX9lvEWXn9JXe2Kcnuc00BH9L1F2vxKgAAAJgp3mfQKd5n + 0AAAAAtzc2gtZWQyNTUxOQAAACCXjXHQTLXeCaPX9lvEWXn9JXe2Kcnuc00BH9L1F2vxKg + AAAEBia7mAQFoLBILlvTJroTkOUomzfcPY9ckpViQOjYFkAZeNcdBMtd4Jo9f2W8RZef0l + d7Ypye5zTQEf0vUXa/EqAAAAE3ZzY29kZUAzY2Y4MWY5YmM3MmQBAg== + -----END OPENSSH PRIVATE KEY-----` +) + +func TestWorkspaceOwnerDatasource(t *testing.T) { + t.Run("OK", func(t *testing.T) { + t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") + t.Setenv("CODER_WORKSPACE_OWNER", "owner123") + t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") + t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") + t.Setenv("CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY", testSSHEd25519PublicKey) + t.Setenv("CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY", testSSHEd25519PrivateKey) + t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) + t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", `supersecret`) + t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", `alsosupersecret`) + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" {} + data "coder_workspace_owner" "me" {} + `, + Check: func(s *terraform.State) error { + require.Len(t, s.Modules, 1) + require.Len(t, s.Modules[0].Resources, 1) + resource := s.Modules[0].Resources["data.coder_workspace_owner.me"] + require.NotNil(t, resource) + + attrs := resource.Primary.Attributes + assert.Equal(t, "11111111-1111-1111-1111-111111111111", attrs["id"]) + assert.Equal(t, "owner123", attrs["name"]) + assert.Equal(t, "Mr Owner", attrs["full_name"]) + assert.Equal(t, "owner123@example.com", attrs["email"]) + assert.Equal(t, testSSHEd25519PublicKey, attrs["ssh_public_key"]) + assert.Equal(t, testSSHEd25519PrivateKey, attrs["ssh_private_key"]) + assert.Equal(t, `group1`, attrs["groups.0"]) + assert.Equal(t, `group2`, attrs["groups.1"]) + assert.Equal(t, `supersecret`, attrs["session_token"]) + assert.Equal(t, `alsosupersecret`, attrs["oidc_access_token"]) + return nil + }, + }}, + }) + }) + + t.Run("Defaults", func(t *testing.T) { + for _, v := range []string{ + "CODER_WORKSPACE_OWNER", + "CODER_WORKSPACE_OWNER_ID", + "CODER_WORKSPACE_OWNER_EMAIL", + "CODER_WORKSPACE_OWNER_NAME", + "CODER_WORKSPACE_OWNER_SESSION_TOKEN", + "CODER_WORKSPACE_OWNER_GROUPS", + "CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", + "CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY", + "CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY", + } { // https://github.com/golang/go/issues/52817 + t.Setenv(v, "") + os.Unsetenv(v) + } + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" {} + data "coder_workspace_owner" "me" {} + `, + Check: func(s *terraform.State) error { + require.Len(t, s.Modules, 1) + require.Len(t, s.Modules[0].Resources, 1) + resource := s.Modules[0].Resources["data.coder_workspace_owner.me"] + require.NotNil(t, resource) + + attrs := resource.Primary.Attributes + assert.NotEmpty(t, attrs["id"]) + assert.Equal(t, "default", attrs["name"]) + assert.Equal(t, "default", attrs["full_name"]) + assert.Equal(t, "default@example.com", attrs["email"]) + assert.Empty(t, attrs["ssh_public_key"]) + assert.Empty(t, attrs["ssh_private_key"]) + assert.Empty(t, attrs["groups.0"]) + assert.Empty(t, attrs["session_token"]) + assert.Empty(t, attrs["oidc_access_token"]) + return nil + }, + }}, + }) + }) +} diff --git a/provider/workspace_test.go b/provider/workspace_test.go index d5866af5..d285b30c 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -14,10 +14,12 @@ import ( func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER", "owner123") + t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) + t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -47,6 +49,7 @@ func TestWorkspace(t *testing.T) { assert.Equal(t, "https://example.com:8080", attribs["access_url"]) assert.Equal(t, "8080", attribs["access_port"]) assert.Equal(t, "owner123", attribs["owner"]) + assert.Equal(t, "11111111-1111-1111-1111-111111111111", attribs["owner_id"]) assert.Equal(t, "Mr Owner", attribs["owner_name"]) assert.Equal(t, "owner123@example.com", attribs["owner_email"]) assert.Equal(t, "group1", attribs["owner_groups.0"]) @@ -54,6 +57,7 @@ func TestWorkspace(t *testing.T) { assert.Equal(t, "templateID", attribs["template_id"]) assert.Equal(t, "template123", attribs["template_name"]) assert.Equal(t, "v1.2.3", attribs["template_version"]) + assert.Equal(t, "supersecret", attribs["owner_oidc_access_token"]) return nil }, }}, From 96993eb480472411a8bfb198893d4a8752a38a94 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 27 May 2024 09:30:48 +0100 Subject: [PATCH 074/173] fix: provider: coder_workspace_owner: avoid setting null values (#232) * chore: add coder_workspace_owner to TestProviderEmpty, rm unused struct * fix: do not set null values --- provider/provider_test.go | 1 + provider/workspace_owner.go | 33 +++++++++------------------------ 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/provider/provider_test.go b/provider/provider_test.go index c1e3c686..7069db09 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -33,6 +33,7 @@ func TestProviderEmpty(t *testing.T) { provider "coder" {} data "coder_provisioner" "me" {} data "coder_workspace" "me" {} + data "coder_workspace_owner" "me" {} data "coder_external_auth" "git" { id = "git" } diff --git a/provider/workspace_owner.go b/provider/workspace_owner.go index 5721b5c5..13e36187 100644 --- a/provider/workspace_owner.go +++ b/provider/workspace_owner.go @@ -11,62 +11,47 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -type Role struct { - Name string `json:"name"` - DisplayName string `json:"display-name"` -} - func workspaceOwnerDataSource() *schema.Resource { return &schema.Resource{ Description: "Use this data source to fetch information about the workspace owner.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { - if idStr, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_ID"); ok { + if idStr := os.Getenv("CODER_WORKSPACE_OWNER_ID"); idStr != "" { rd.SetId(idStr) } else { rd.SetId(uuid.NewString()) } - if username, ok := os.LookupEnv("CODER_WORKSPACE_OWNER"); ok { + if username := os.Getenv("CODER_WORKSPACE_OWNER"); username != "" { _ = rd.Set("name", username) } else { _ = rd.Set("name", "default") } - if fullname, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_NAME"); ok { + if fullname := os.Getenv("CODER_WORKSPACE_OWNER_NAME"); fullname != "" { _ = rd.Set("full_name", fullname) } else { // compat: field can be blank, fill in default _ = rd.Set("full_name", "default") } - if email, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_EMAIL"); ok { + if email := os.Getenv("CODER_WORKSPACE_OWNER_EMAIL"); email != "" { _ = rd.Set("email", email) } else { _ = rd.Set("email", "default@example.com") } - if sshPubKey, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY"); ok { - _ = rd.Set("ssh_public_key", sshPubKey) - } - - if sshPrivKey, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY"); ok { - _ = rd.Set("ssh_private_key", sshPrivKey) - } + _ = rd.Set("ssh_public_key", os.Getenv("CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY")) + _ = rd.Set("ssh_private_key", os.Getenv("CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY")) var groups []string if groupsRaw, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_GROUPS"); ok { if err := json.NewDecoder(strings.NewReader(groupsRaw)).Decode(&groups); err != nil { return diag.Errorf("invalid user groups: %s", err.Error()) } - _ = rd.Set("groups", groups) - } - - if tok, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_SESSION_TOKEN"); ok { - _ = rd.Set("session_token", tok) } + _ = rd.Set("groups", groups) - if tok, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN"); ok { - _ = rd.Set("oidc_access_token", tok) - } + _ = rd.Set("session_token", os.Getenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN")) + _ = rd.Set("oidc_access_token", os.Getenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN")) return nil }, From 4f417ad002cd7620d5f830dcbd5831865cb51946 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 28 May 2024 15:34:21 +0100 Subject: [PATCH 075/173] chore: update to go1.22 (#234) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- go.mod | 4 +++- go.sum | 6 ++++++ 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fa152f4d..1a56c6f8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "terraform-provider-coder", - "image": "mcr.microsoft.com/devcontainers/go:1.20", + "image": "mcr.microsoft.com/devcontainers/go:1.22", "features": { "ghcr.io/devcontainers/features/terraform:1": { "installTerraformDocs": true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 00fd83ec..ad8d96c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.20.6 + go-version: 1.22.3 - name: Import GPG key id: import_gpg diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fefaf2f5..2a4a6bce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.22" id: go - name: Check out code into the Go module directory @@ -59,7 +59,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.22" id: go - uses: hashicorp/setup-terraform@v3 @@ -89,7 +89,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.22" id: go - uses: hashicorp/setup-terraform@v3 diff --git a/go.mod b/go.mod index 7af7f224..b7c3b071 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/coder/terraform-provider-coder -go 1.20 +go 1.22 + +toolchain go1.22.3 require ( github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 93ed263d..01bac480 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,7 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= +github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= @@ -35,6 +36,7 @@ github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6 github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -102,6 +104,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -115,6 +118,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= @@ -136,6 +140,7 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= +github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -151,6 +156,7 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From df757123402eb41ab4e26ca0a58123ab87d679bb Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 4 Jun 2024 10:44:00 +0100 Subject: [PATCH 076/173] chore: add integration test for provider (#233) This PR adds integration tests for the provider against an arbitrary version of Coder. Example usage: ``` CODER_VERSION="v2.10.0-devel-3a9a7d199-amd64" go test -v ./integration Testing methodology: ``` - Create an ephemeral Coder instance running in a container - Perform initial setup - Import a predefined template that creates a single file - Create a workspace that populates the file with the actual output - Compare the actual versus expected output --- Makefile | 14 +- README.md | 51 ++++-- go.mod | 41 ++++- go.sum | 127 ++++++++++++-- integration/integration_test.go | 247 +++++++++++++++++++++++++++ integration/test-data-source/main.tf | 65 +++++++ 6 files changed, 506 insertions(+), 39 deletions(-) create mode 100644 integration/integration_test.go create mode 100644 integration/test-data-source/main.tf diff --git a/Makefile b/Makefile index d694a040..43c93a83 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,19 @@ fmt: gen: go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest +build: terraform-provider-coder + +# Builds the provider. Note that as coder/coder is based on +# alpine, we need to disable cgo. +terraform-provider-coder: provider/*.go main.go + CGO_ENABLED=0 go build . + +# Run integration tests +.PHONY: test-integration +test-integration: terraform-provider-coder + go test -v ./integration + # Run acceptance tests .PHONY: testacc testacc: - TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m \ No newline at end of file + TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m diff --git a/README.md b/README.md index d4b48fac..2bceb73a 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ to setup your local Terraform to use your local version rather than the registry 1. Create a file named `.terraformrc` in your `$HOME` directory 2. Add the following content: + ```hcl provider_installation { # Override the coder/coder provider to use your local version @@ -33,18 +34,46 @@ to setup your local Terraform to use your local version rather than the registry direct {} } ``` + 3. (optional, but recommended) Validate your configuration: - 1. Create a new `main.tf` file and include: - ```hcl - terraform { - required_providers { - coder = { - source = "coder/coder" - } - } - } - ``` + 1. Create a new `main.tf` file and include: + ```hcl + terraform { + required_providers { + coder = { + source = "coder/coder" + } + } + } + ``` 2. Run `terraform init` and observe a warning like `Warning: Provider development overrides are in effect` 4. Run `go build -o terraform-provider-coder` to build the provider binary, which Terraform will try locate and execute 5. All local Terraform runs will now use your local provider! -6. _**NOTE**: we vendor in this provider into `github.com/coder/coder`, so if you're testing with a local clone then you should also run `go mod edit -replace github.com/coder/terraform-provider-coder=/path/to/terraform-provider-coder` in your clone._ \ No newline at end of file +6. _**NOTE**: we vendor in this provider into `github.com/coder/coder`, so if you're testing with a local clone then you should also run `go mod edit -replace github.com/coder/terraform-provider-coder=/path/to/terraform-provider-coder` in your clone._ + +#### Terraform Acceptance Tests + +To run Terraform acceptance tests, run `make testacc`. This will test the provider against the locally installed version of Terraform. + +> **Note:** our [CI workflow](./github/workflows/test.yml) runs a test matrix against multiple Terraform versions. + +#### Integration Tests + +The tests under the `./integration` directory perform the following steps: + +- Build the local version of the provider, +- Run an in-memory Coder instance with a specified version, +- Validate the behaviour of the local provider against that specific version of Coder. + +To run these integration tests locally: + +1. Pull the version of the Coder image you wish to test: + + ```console + docker pull ghcr.io/coder/coder:main-x.y.z-devel-abcd1234 + ``` + +1. Run `CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. + +> **Note:** you can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. +> For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`. diff --git a/go.mod b/go.mod index b7c3b071..9eb4c7d3 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22 toolchain go1.22.3 require ( + github.com/docker/docker v26.1.3+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 @@ -18,10 +19,18 @@ require ( github.com/Microsoft/go-winio v0.5.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -47,20 +56,34 @@ require ( github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/oklog/run v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/sdk v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index 01bac480..0919b1c8 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= @@ -17,14 +19,28 @@ github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJE github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= +github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -35,23 +51,33 @@ github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -107,6 +133,8 @@ github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZ github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -138,13 +166,24 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +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.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -159,6 +198,8 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -177,41 +218,76 @@ github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37w github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/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-20200301022130-244492dfa37a/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-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -221,32 +297,45 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -262,3 +351,5 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/integration/integration_test.go b/integration/integration_test.go new file mode 100644 index 00000000..f2c55ed8 --- /dev/null +++ b/integration/integration_test.go @@ -0,0 +1,247 @@ +package integration + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + "testing" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/stdcopy" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestIntegration performs an integration test against an ephemeral Coder deployment. +// For each directory containing a `main.tf` under `/integration`, performs the following: +// - Pushes the template to a temporary Coder instance running in Docker +// - Creates a workspace from the template. Templates here are expected to create a +// local_file resource containing JSON that can be marshalled as a map[string]string +// - Fetches the content of the JSON file created and compares it against the expected output. +// +// NOTE: all interfaces to this Coder deployment are performed without github.com/coder/coder/v2/codersdk +// in order to avoid a circular dependency. +func TestIntegration(t *testing.T) { + if os.Getenv("TF_ACC") == "1" { + t.Skip("Skipping integration tests during tf acceptance tests") + } + + timeoutStr := os.Getenv("TIMEOUT_MINS") + if timeoutStr == "" { + timeoutStr = "10" + } + timeoutMins, err := strconv.Atoi(timeoutStr) + require.NoError(t, err, "invalid value specified for timeout") + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutMins)*time.Minute) + t.Cleanup(cancel) + + // Given: we have an existing Coder deployment running locally + ctrID := setup(ctx, t) + + for _, tt := range []struct { + // Name of the folder under `integration/` containing a test template + templateName string + // map of string to regex to be passed to assertOutput() + expectedOutput map[string]string + }{ + { + templateName: "test-data-source", + expectedOutput: map[string]string{ + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": `test-data-source`, + "workspace.owner": `testing`, + "workspace.owner_email": `testing@coder\.com`, + "workspace.owner_groups": `\[\]`, + "workspace.owner_id": `[a-zA-Z0-9]+`, + "workspace.owner_name": `default`, + "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration + "workspace.owner_session_token": `[a-zA-Z0-9-]+`, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `test-data-source`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, + "workspace_owner.email": `testing@coder\.com`, + "workspace_owner.full_name": `default`, + "workspace_owner.groups": `\[\]`, + "workspace_owner.id": `[a-zA-Z0-9-]+`, + "workspace_owner.name": `testing`, + "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration + "workspace_owner.session_token": `.+`, + "workspace_owner.ssh_private_key": `^$`, // Depends on coder/coder#13366 + "workspace_owner.ssh_public_key": `^$`, // Depends on coder/coder#13366 + }, + }, + } { + t.Run(tt.templateName, func(t *testing.T) { + // Import named template + _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates push %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, tt.templateName, tt.templateName, tt.templateName)) + require.Equal(t, 0, rc) + // Create a workspace + _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s --yes`, tt.templateName, tt.templateName)) + require.Equal(t, 0, rc) + // Fetch the output created by the template + out, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`cat /tmp/%s.json`, tt.templateName)) + require.Equal(t, 0, rc) + actual := make(map[string]string) + require.NoError(t, json.NewDecoder(strings.NewReader(out)).Decode(&actual)) + assertOutput(t, tt.expectedOutput, actual) + }) + } +} + +func setup(ctx context.Context, t *testing.T) string { + var ( + // For this test to work, we pass in a custom terraformrc to use + // the locally built version of the provider. + testTerraformrc = `provider_installation { + dev_overrides { + "coder/coder" = "/src" + } + direct{} + }` + localURL = "http://localhost:3000" + ) + + coderImg := os.Getenv("CODER_IMAGE") + if coderImg == "" { + coderImg = "ghcr.io/coder/coder" + } + + coderVersion := os.Getenv("CODER_VERSION") + if coderVersion == "" { + coderVersion = "latest" + } + + t.Logf("using coder image %s:%s", coderImg, coderVersion) + + // Ensure the binary is built + binPath, err := filepath.Abs("../terraform-provider-coder") + require.NoError(t, err) + if _, err := os.Stat(binPath); os.IsNotExist(err) { + t.Fatalf("not found: %q - please build the provider first", binPath) + } + tmpDir := t.TempDir() + // Create a terraformrc to point to our freshly built provider! + tfrcPath := filepath.Join(tmpDir, "integration.tfrc") + err = os.WriteFile(tfrcPath, []byte(testTerraformrc), 0o644) + require.NoError(t, err, "write terraformrc to tempdir") + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + require.NoError(t, err, "init docker client") + + srcPath, err := filepath.Abs("..") + require.NoError(t, err, "get abs path of parent") + t.Logf("src path is %s\n", srcPath) + + // Stand up a temporary Coder instance + ctr, err := cli.ContainerCreate(ctx, &container.Config{ + Image: coderImg + ":" + coderVersion, + Env: []string{ + "CODER_ACCESS_URL=" + localURL, // Set explicitly to avoid creating try.coder.app URLs. + "CODER_IN_MEMORY=true", // We don't necessarily care about real persistence here. + "CODER_TELEMETRY_ENABLE=false", // Avoid creating noise. + "TF_CLI_CONFIG_FILE=/tmp/integration.tfrc", // Our custom tfrc from above. + }, + Labels: map[string]string{}, + }, &container.HostConfig{ + Binds: []string{ + tfrcPath + ":/tmp/integration.tfrc", // Custom tfrc from above. + srcPath + ":/src", // Bind-mount in the repo with the built binary and templates. + }, + }, nil, nil, "") + require.NoError(t, err, "create test deployment") + + t.Logf("created container %s\n", ctr.ID) + t.Cleanup(func() { // Make sure we clean up after ourselves. + // TODO: also have this execute if you Ctrl+C! + t.Logf("stopping container %s\n", ctr.ID) + _ = cli.ContainerRemove(ctx, ctr.ID, container.RemoveOptions{ + Force: true, + }) + }) + + err = cli.ContainerStart(ctx, ctr.ID, container.StartOptions{}) + require.NoError(t, err, "start container") + t.Logf("started container %s\n", ctr.ID) + + // nolint:gosec // For testing only. + var ( + testEmail = "testing@coder.com" + testPassword = "InsecurePassw0rd!" + testUsername = "testing" + ) + + // Wait for container to come up + require.Eventually(t, func() bool { + _, rc := execContainer(ctx, t, ctr.ID, fmt.Sprintf(`curl -s --fail %s/api/v2/buildinfo`, localURL)) + if rc == 0 { + return true + } + t.Logf("not ready yet...") + return false + }, 10*time.Second, time.Second, "coder failed to become ready in time") + + // Perform first time setup + _, rc := execContainer(ctx, t, ctr.ID, fmt.Sprintf(`coder login %s --first-user-email=%q --first-user-password=%q --first-user-trial=false --first-user-username=%q`, localURL, testEmail, testPassword, testUsername)) + require.Equal(t, 0, rc, "failed to perform first-time setup") + return ctr.ID +} + +// execContainer executes the given command in the given container and returns +// the output and the exit code of the command. +func execContainer(ctx context.Context, t *testing.T, containerID, command string) (string, int) { + t.Helper() + t.Logf("exec container cmd: %q", command) + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + require.NoError(t, err, "connect to docker") + defer cli.Close() + execConfig := types.ExecConfig{ + AttachStdout: true, + AttachStderr: true, + Cmd: []string{"/bin/sh", "-c", command}, + } + ex, err := cli.ContainerExecCreate(ctx, containerID, execConfig) + require.NoError(t, err, "create container exec") + resp, err := cli.ContainerExecAttach(ctx, ex.ID, types.ExecStartCheck{}) + require.NoError(t, err, "attach to container exec") + defer resp.Close() + var buf bytes.Buffer + _, err = stdcopy.StdCopy(&buf, &buf, resp.Reader) + require.NoError(t, err, "read stdout") + out := buf.String() + t.Log("exec container output:\n" + out) + execResp, err := cli.ContainerExecInspect(ctx, ex.ID) + require.NoError(t, err, "get exec exit code") + return out, execResp.ExitCode +} + +// assertOutput asserts that, for each key-value pair in expected: +// 1. actual[k] as a regex matches expected[k], and +// 2. the set of keys of expected are not a subset of actual. +func assertOutput(t *testing.T, expected, actual map[string]string) { + t.Helper() + + for expectedKey, expectedValExpr := range expected { + actualVal := actual[expectedKey] + assert.Regexp(t, expectedValExpr, actualVal) + } + for actualKey := range actual { + _, ok := expected[actualKey] + assert.True(t, ok, "unexpected field in actual %q=%q", actualKey, actual[actualKey]) + } +} diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf new file mode 100644 index 00000000..580592cb --- /dev/null +++ b/integration/test-data-source/main.tf @@ -0,0 +1,65 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +// TODO: test coder_external_auth and coder_git_auth +// data coder_external_auth "me" {} +// data coder_git_auth "me" {} +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +locals { + # NOTE: these must all be strings in the output + output = { + "provisioner.arch" : data.coder_provisioner.me.arch, + "provisioner.id" : data.coder_provisioner.me.id, + "provisioner.os" : data.coder_provisioner.me.os, + "workspace.access_port" : tostring(data.coder_workspace.me.access_port), + "workspace.access_url" : data.coder_workspace.me.access_url, + "workspace.id" : data.coder_workspace.me.id, + "workspace.name" : data.coder_workspace.me.name, + "workspace.owner" : data.coder_workspace.me.owner, + "workspace.owner_email" : data.coder_workspace.me.owner_email, + "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), + "workspace.owner_id" : data.coder_workspace.me.owner_id, + "workspace.owner_name" : data.coder_workspace.me.owner_name, + "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, + "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, + "workspace.start_count" : tostring(data.coder_workspace.me.start_count), + "workspace.template_id" : data.coder_workspace.me.template_id, + "workspace.template_name" : data.coder_workspace.me.template_name, + "workspace.template_version" : data.coder_workspace.me.template_version, + "workspace.transition" : data.coder_workspace.me.transition, + "workspace_owner.email" : data.coder_workspace_owner.me.email, + "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, + "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), + "workspace_owner.id" : data.coder_workspace_owner.me.id, + "workspace_owner.name" : data.coder_workspace_owner.me.name, + "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, + "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, + "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, + "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} From ecdd884abc896f50dd82a7898830c440952b443e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:34:36 +0100 Subject: [PATCH 077/173] build(deps): Bump github.com/docker/docker (#239) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.1.3+incompatible to 26.1.4+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v26.1.3...v26.1.4) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9eb4c7d3..625aae19 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 toolchain go1.22.3 require ( - github.com/docker/docker v26.1.3+incompatible + github.com/docker/docker v26.1.4+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 diff --git a/go.sum b/go.sum index 0919b1c8..d07d5ff3 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= -github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= +github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= From 62fa89d7ed61b00c175f3dc17d70b3fcd3fd0e40 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 10 Jun 2024 09:38:41 +0100 Subject: [PATCH 078/173] ci: run integration test (#240) --- .github/workflows/test.yml | 10 +++++++++ integration/integration_test.go | 37 ++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a4a6bce..217c065f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,9 +33,19 @@ jobs: go mod download - name: Build + env: + CGO_ENABLED: "0" run: | go build -v . + - name: Run integration test + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: "latest" + run: | + go test -v ./integration + # run acceptance tests in a matrix with Terraform core versions test: name: Matrix Test diff --git a/integration/integration_test.go b/integration/integration_test.go index f2c55ed8..1c2046be 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "io" "os" "path/filepath" "runtime" @@ -15,6 +16,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" "github.com/stretchr/testify/assert" @@ -44,17 +46,14 @@ func TestIntegration(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutMins)*time.Minute) t.Cleanup(cancel) - // Given: we have an existing Coder deployment running locally - ctrID := setup(ctx, t) - for _, tt := range []struct { // Name of the folder under `integration/` containing a test template - templateName string + name string // map of string to regex to be passed to assertOutput() expectedOutput map[string]string }{ { - templateName: "test-data-source", + name: "test-data-source", expectedOutput: map[string]string{ "provisioner.arch": runtime.GOARCH, "provisioner.id": `[a-zA-Z0-9-]+`, @@ -82,20 +81,22 @@ func TestIntegration(t *testing.T) { "workspace_owner.name": `testing`, "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration "workspace_owner.session_token": `.+`, - "workspace_owner.ssh_private_key": `^$`, // Depends on coder/coder#13366 - "workspace_owner.ssh_public_key": `^$`, // Depends on coder/coder#13366 + "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, + "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, }, }, } { - t.Run(tt.templateName, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { + // Given: we have an existing Coder deployment running locally + ctrID := setup(ctx, t, tt.name) // Import named template - _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates push %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, tt.templateName, tt.templateName, tt.templateName)) + _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates push %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, tt.name, tt.name, tt.name)) require.Equal(t, 0, rc) // Create a workspace - _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s --yes`, tt.templateName, tt.templateName)) + _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s --yes`, tt.name, tt.name)) require.Equal(t, 0, rc) // Fetch the output created by the template - out, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`cat /tmp/%s.json`, tt.templateName)) + out, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`cat /tmp/%s.json`, tt.name)) require.Equal(t, 0, rc) actual := make(map[string]string) require.NoError(t, json.NewDecoder(strings.NewReader(out)).Decode(&actual)) @@ -104,7 +105,7 @@ func TestIntegration(t *testing.T) { } } -func setup(ctx context.Context, t *testing.T) string { +func setup(ctx context.Context, t *testing.T, name string) string { var ( // For this test to work, we pass in a custom terraformrc to use // the locally built version of the provider. @@ -148,9 +149,17 @@ func setup(ctx context.Context, t *testing.T) string { require.NoError(t, err, "get abs path of parent") t.Logf("src path is %s\n", srcPath) + // Ensure the image is available locally. + refStr := coderImg + ":" + coderVersion + t.Logf("ensuring image %q", refStr) + resp, err := cli.ImagePull(ctx, refStr, image.PullOptions{}) + require.NoError(t, err) + _, err = io.ReadAll(resp) + require.NoError(t, err) + // Stand up a temporary Coder instance ctr, err := cli.ContainerCreate(ctx, &container.Config{ - Image: coderImg + ":" + coderVersion, + Image: refStr, Env: []string{ "CODER_ACCESS_URL=" + localURL, // Set explicitly to avoid creating try.coder.app URLs. "CODER_IN_MEMORY=true", // We don't necessarily care about real persistence here. @@ -163,7 +172,7 @@ func setup(ctx context.Context, t *testing.T) string { tfrcPath + ":/tmp/integration.tfrc", // Custom tfrc from above. srcPath + ":/src", // Bind-mount in the repo with the built binary and templates. }, - }, nil, nil, "") + }, nil, nil, "terraform-provider-coder-integration-"+name) require.NoError(t, err, "create test deployment") t.Logf("created container %s\n", ctr.ID) From d51a4a7c793d326ae80cb40ad3b18919fcf2ab02 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 25 Jun 2024 14:52:58 +0200 Subject: [PATCH 079/173] feat: annotate resources with`SchemaVersion` (#244) --- .gitignore | 5 ++- integration/integration_test.go | 2 ++ provider/agent.go | 7 +++-- provider/app.go | 2 ++ provider/env.go | 2 ++ provider/externalauth.go | 7 +++-- provider/gitauth.go | 7 +++-- provider/helpers/env.go | 31 +++++++++++++++++++ provider/metadata.go | 2 ++ provider/parameter.go | 2 ++ provider/provisioner.go | 2 ++ provider/script.go | 2 ++ provider/workspace.go | 54 +++++++++++---------------------- provider/workspace_tags.go | 2 ++ 14 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 provider/helpers/env.go diff --git a/.gitignore b/.gitignore index e5a80c26..4d5d5ad6 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,7 @@ website/vendor !command/test-fixtures/**/.terraform/ # Keep windows files with windows line endings -*.winfile eol=crlf \ No newline at end of file +*.winfile eol=crlf + +# Binary +terraform-provider-coder diff --git a/integration/integration_test.go b/integration/integration_test.go index 1c2046be..cf58b99e 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -164,7 +164,9 @@ func setup(ctx context.Context, t *testing.T, name string) string { "CODER_ACCESS_URL=" + localURL, // Set explicitly to avoid creating try.coder.app URLs. "CODER_IN_MEMORY=true", // We don't necessarily care about real persistence here. "CODER_TELEMETRY_ENABLE=false", // Avoid creating noise. + "CODER_VERBOSE=TRUE", // Debug logging. "TF_CLI_CONFIG_FILE=/tmp/integration.tfrc", // Our custom tfrc from above. + "TF_LOG=DEBUG", // Debug logging in Terraform provider }, Labels: map[string]string{}, }, &container.HostConfig{ diff --git a/provider/agent.go b/provider/agent.go index 7b197870..0ff5ca21 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -3,7 +3,6 @@ package provider import ( "context" "fmt" - "os" "reflect" "strings" @@ -12,10 +11,14 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "golang.org/x/xerrors" + + "github.com/coder/terraform-provider-coder/provider/helpers" ) func agentResource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this resource to associate an agent.", CreateContext: func(_ context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { // This should be a real authentication token! @@ -363,7 +366,7 @@ func updateInitScript(resourceData *schema.ResourceData, i interface{}) diag.Dia if err != nil { return diag.Errorf("parse access url: %s", err) } - script := os.Getenv(fmt.Sprintf("CODER_AGENT_SCRIPT_%s_%s", operatingSystem, arch)) + script := helpers.OptionalEnv(fmt.Sprintf("CODER_AGENT_SCRIPT_%s_%s", operatingSystem, arch)) if script != "" { script = strings.ReplaceAll(script, "${ACCESS_URL}", accessURL.String()) script = strings.ReplaceAll(script, "${AUTH_TYPE}", auth) diff --git a/provider/app.go b/provider/app.go index ed0ac53e..c2690311 100644 --- a/provider/app.go +++ b/provider/app.go @@ -25,6 +25,8 @@ var ( func appResource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this resource to define shortcuts to access applications in a workspace.", CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { resourceData.SetId(uuid.NewString()) diff --git a/provider/env.go b/provider/env.go index 66d03a22..8f55ff8c 100644 --- a/provider/env.go +++ b/provider/env.go @@ -12,6 +12,8 @@ import ( func envResource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: `Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource.`, CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) diff --git a/provider/externalauth.go b/provider/externalauth.go index 31dadd66..13c85fab 100644 --- a/provider/externalauth.go +++ b/provider/externalauth.go @@ -3,15 +3,18 @@ package provider import ( "context" "fmt" - "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/coder/terraform-provider-coder/provider/helpers" ) // externalAuthDataSource returns a schema for an external authentication data source. func externalAuthDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc)", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { id, ok := rd.Get("id").(string) @@ -20,7 +23,7 @@ func externalAuthDataSource() *schema.Resource { } rd.SetId(id) - accessToken := os.Getenv(ExternalAuthAccessTokenEnvironmentVariable(id)) + accessToken := helpers.OptionalEnv(ExternalAuthAccessTokenEnvironmentVariable(id)) rd.Set("access_token", accessToken) return nil }, diff --git a/provider/gitauth.go b/provider/gitauth.go index aa36d493..72c05bcd 100644 --- a/provider/gitauth.go +++ b/provider/gitauth.go @@ -3,15 +3,18 @@ package provider import ( "context" "fmt" - "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/coder/terraform-provider-coder/provider/helpers" ) // gitAuthDataSource returns a schema for a Git authentication data source. func gitAuthDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + DeprecationMessage: "Use the `coder_external_auth` data source instead.", Description: "Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { @@ -25,7 +28,7 @@ func gitAuthDataSource() *schema.Resource { } rd.SetId(id) - accessToken := os.Getenv(GitAuthAccessTokenEnvironmentVariable(id)) + accessToken := helpers.OptionalEnv(GitAuthAccessTokenEnvironmentVariable(id)) rd.Set("access_token", accessToken) return nil diff --git a/provider/helpers/env.go b/provider/helpers/env.go new file mode 100644 index 00000000..b1007820 --- /dev/null +++ b/provider/helpers/env.go @@ -0,0 +1,31 @@ +package helpers + +import ( + "fmt" + "os" +) + +// RequireEnv requires environment variable to be present. +func RequireEnv(name string) (string, error) { + val := os.Getenv(name) + if val == "" { + return "", fmt.Errorf("%s is required", name) + } + return val, nil +} + +// OptionalEnv returns the value for environment variable if it exists, +// otherwise returns an empty string. +func OptionalEnv(name string) string { + return OptionalEnvOrDefault(name, "") +} + +// OptionalEnvOrDefault returns the value for environment variable if it exists, +// otherwise returns the default value. +func OptionalEnvOrDefault(name, defaultValue string) string { + val := os.Getenv(name) + if val == "" { + return defaultValue + } + return val +} diff --git a/provider/metadata.go b/provider/metadata.go index 3bd5e6f5..00b488e4 100644 --- a/provider/metadata.go +++ b/provider/metadata.go @@ -11,6 +11,8 @@ import ( func metadataResource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this resource to attach metadata to a resource. They will be " + "displayed in the Coder dashboard.", CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { diff --git a/provider/parameter.go b/provider/parameter.go index 12dbc019..d0f71dab 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -63,6 +63,8 @@ type Parameter struct { func parameterDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this data source to configure editable options for workspaces.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) diff --git a/provider/provisioner.go b/provider/provisioner.go index 314e89cd..9d356798 100644 --- a/provider/provisioner.go +++ b/provider/provisioner.go @@ -11,6 +11,8 @@ import ( func provisionerDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this data source to get information about the Coder provisioner.", ReadContext: func(c context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) diff --git a/provider/script.go b/provider/script.go index 4a05440e..1474dbd2 100644 --- a/provider/script.go +++ b/provider/script.go @@ -15,6 +15,8 @@ var ScriptCRONParser = cron.NewParser(cron.Second | cron.Minute | cron.Hour | cr func scriptResource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this resource to run a script from an agent.", CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) diff --git a/provider/workspace.go b/provider/workspace.go index 098d64cc..f06e9e1e 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -3,44 +3,38 @@ package provider import ( "context" "encoding/json" - "os" "reflect" "strconv" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/coder/terraform-provider-coder/provider/helpers" ) func workspaceDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this data source to get information for the active workspace build.", ReadContext: func(c context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { - transition := os.Getenv("CODER_WORKSPACE_TRANSITION") - if transition == "" { - // Default to start! - transition = "start" - } + transition := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_TRANSITION", "start") // Default to start! _ = rd.Set("transition", transition) + count := 0 if transition == "start" { count = 1 } _ = rd.Set("start_count", count) - owner := os.Getenv("CODER_WORKSPACE_OWNER") - if owner == "" { - owner = "default" - } + owner := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER", "default") _ = rd.Set("owner", owner) - ownerEmail := os.Getenv("CODER_WORKSPACE_OWNER_EMAIL") - if ownerEmail == "" { - ownerEmail = "default@example.com" - } + ownerEmail := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_EMAIL", "default@example.com") _ = rd.Set("owner_email", ownerEmail) - ownerGroupsText := os.Getenv("CODER_WORKSPACE_OWNER_GROUPS") + ownerGroupsText := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_GROUPS") var ownerGroups []string if ownerGroupsText != "" { err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) @@ -50,43 +44,31 @@ func workspaceDataSource() *schema.Resource { } _ = rd.Set("owner_groups", ownerGroups) - ownerName := os.Getenv("CODER_WORKSPACE_OWNER_NAME") - if ownerName == "" { - ownerName = "default" - } + ownerName := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_NAME", "default") _ = rd.Set("owner_name", ownerName) - ownerID := os.Getenv("CODER_WORKSPACE_OWNER_ID") - if ownerID == "" { - ownerID = uuid.Nil.String() - } + ownerID := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_ID", uuid.Nil.String()) _ = rd.Set("owner_id", ownerID) - ownerOIDCAccessToken := os.Getenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN") + ownerOIDCAccessToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN") _ = rd.Set("owner_oidc_access_token", ownerOIDCAccessToken) - name := os.Getenv("CODER_WORKSPACE_NAME") - if name == "" { - name = "default" - } + name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) - sessionToken := os.Getenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN") + sessionToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_SESSION_TOKEN") _ = rd.Set("owner_session_token", sessionToken) - id := os.Getenv("CODER_WORKSPACE_ID") - if id == "" { - id = uuid.NewString() - } + id := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_ID", uuid.NewString()) rd.SetId(id) - templateID := os.Getenv("CODER_WORKSPACE_TEMPLATE_ID") + templateID := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_ID") // FIXME switch to `helpers.RequireEnv(...)` _ = rd.Set("template_id", templateID) - templateName := os.Getenv("CODER_WORKSPACE_TEMPLATE_NAME") + templateName := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_NAME") // FIXME switch to `helpers.RequireEnv(...)` _ = rd.Set("template_name", templateName) - templateVersion := os.Getenv("CODER_WORKSPACE_TEMPLATE_VERSION") + templateVersion := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_VERSION") // FIXME switch to `helpers.RequireEnv(...)` _ = rd.Set("template_version", templateVersion) config, valid := i.(config) diff --git a/provider/workspace_tags.go b/provider/workspace_tags.go index 088ff546..09736d02 100644 --- a/provider/workspace_tags.go +++ b/provider/workspace_tags.go @@ -14,6 +14,8 @@ type WorkspaceTags struct { func workspaceTagDataSource() *schema.Resource { return &schema.Resource{ + SchemaVersion: 1, + Description: "Use this data source to configure workspace tags to select provisioners.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) From b73066b8638522272627b780277512014a842992 Mon Sep 17 00:00:00 2001 From: Stephen Kirby <58410745+stirby@users.noreply.github.com> Date: Tue, 25 Jun 2024 16:48:36 -0500 Subject: [PATCH 080/173] chore(docs): move coder_parameter example (#243) * moved coder_parameter * swapped test target, renamed parameter example file * make gen * removed coder agent examples from test * attempting data source testing * added git auth to test * reverted git auth test * Refactor examples_test.go * took a stab at expanding example test * added provider to coder_ap * manually reverted test changes --------- Co-authored-by: Marcin Tojek --- docs/data-sources/git_auth.md | 3 +- docs/data-sources/parameter.md | 122 +++++++++++++++++- docs/data-sources/workspace_tags.md | 53 ++++++++ .../coder_git_auth/data-source.tf | 3 +- .../coder_parameter/data-source.tf} | 0 .../coder_workspace_tags/data-source.tf} | 0 provider/examples_test.go | 24 ++-- 7 files changed, 190 insertions(+), 15 deletions(-) rename examples/{resources/coder_parameter/resource.tf => data-sources/coder_parameter/data-source.tf} (100%) rename examples/{resources/coder_workspace_tags/resource.tf => data-sources/coder_workspace_tags/data-source.tf} (100%) diff --git a/docs/data-sources/git_auth.md b/docs/data-sources/git_auth.md index 53e01981..fe64805e 100644 --- a/docs/data-sources/git_auth.md +++ b/docs/data-sources/git_auth.md @@ -13,8 +13,7 @@ Use this data source to require users to authenticate with a Git provider prior ## Example Usage ```terraform -provider "coder" { -} +provider "coder" {} data "coder_git_auth" "github" { # Matches the ID of the git auth provider in Coder. diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 4bded2d3..9c6a11f5 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -10,7 +10,127 @@ description: |- Use this data source to configure editable options for workspaces. - +## Example Usage + +```terraform +provider "coder" {} + +data "coder_parameter" "example" { + name = "Region" + description = "Specify a region to place your workspace." + mutable = false + type = "string" + default = "asia-central1-a" + option { + value = "us-central1-a" + name = "US Central" + icon = "/icon/usa.svg" + } + option { + value = "asia-central1-a" + name = "Asia" + icon = "/icon/asia.svg" + } +} + +data "coder_parameter" "ami" { + name = "Machine Image" + description = <<-EOT + # Provide the machine image + See the [registry](https://container.registry.blah/namespace) for options. + EOT + option { + value = "ami-xxxxxxxx" + name = "Ubuntu" + icon = "/icon/ubuntu.svg" + } +} + +data "coder_parameter" "is_public_instance" { + name = "Is public instance?" + type = "bool" + icon = "/icon/docker.svg" + default = false +} + +data "coder_parameter" "cores" { + name = "CPU Cores" + type = "number" + icon = "/icon/cpu.svg" + default = 3 + order = 10 +} + +data "coder_parameter" "disk_size" { + name = "Disk Size" + type = "number" + default = "5" + order = 8 + validation { + # This can apply to number. + min = 0 + max = 10 + monotonic = "increasing" + } +} + +data "coder_parameter" "cat_lives" { + name = "Cat Lives" + type = "number" + default = "9" + validation { + # This can apply to number. + min = 0 + max = 10 + monotonic = "decreasing" + } +} + +data "coder_parameter" "fairy_tale" { + name = "Fairy Tale" + type = "string" + mutable = true + default = "Hansel and Gretel" + ephemeral = true +} + +data "coder_parameter" "users" { + name = "system_users" + display_name = "System users" + type = "list(string)" + default = jsonencode(["root", "user1", "user2"]) +} + +data "coder_parameter" "home_volume_size" { + name = "Home Volume Size" + description = <<-EOF + How large should your home volume be? + EOF + type = "number" + default = 30 + mutable = true + order = 3 + + option { + name = "30GB" + value = 30 + } + + option { + name = "60GB" + value = 60 + } + + option { + name = "100GB" + value = 100 + } + + validation { + monotonic = "increasing" + } +} +``` ## Schema diff --git a/docs/data-sources/workspace_tags.md b/docs/data-sources/workspace_tags.md index 62f72b0f..010adfe3 100644 --- a/docs/data-sources/workspace_tags.md +++ b/docs/data-sources/workspace_tags.md @@ -10,7 +10,60 @@ description: |- Use this data source to configure workspace tags to select provisioners. +## Example Usage +```terraform +provider "coder" {} + +data "coder_parameter" "os_selector" { + name = "os_selector" + display_name = "Operating System" + mutable = false + + default = "osx" + + option { + icon = "/icons/linux.png" + name = "Linux" + value = "linux" + } + option { + icon = "/icons/osx.png" + name = "OSX" + value = "osx" + } + option { + icon = "/icons/windows.png" + name = "Windows" + value = "windows" + } +} + +data "coder_parameter" "feature_cache_enabled" { + name = "feature_cache_enabled" + display_name = "Enable cache?" + type = "bool" + + default = false +} + +data "coder_parameter" "feature_debug_enabled" { + name = "feature_debug_enabled" + display_name = "Enable debug?" + type = "bool" + + default = true +} + +data "coder_workspace_tags" "custom_workspace_tags" { + tags = { + "cluster" = "developers" + "os" = data.coder_parameter.os_selector.value + "debug" = "${data.coder_parameter.feature_debug_enabled.value}+12345" + "cache" = data.coder_parameter.feature_cache_enabled.value == "true" ? "nix-with-cache" : "no-cache" + } +} +``` ## Schema diff --git a/examples/data-sources/coder_git_auth/data-source.tf b/examples/data-sources/coder_git_auth/data-source.tf index eeed89aa..488554f2 100644 --- a/examples/data-sources/coder_git_auth/data-source.tf +++ b/examples/data-sources/coder_git_auth/data-source.tf @@ -1,5 +1,4 @@ -provider "coder" { -} +provider "coder" {} data "coder_git_auth" "github" { # Matches the ID of the git auth provider in Coder. diff --git a/examples/resources/coder_parameter/resource.tf b/examples/data-sources/coder_parameter/data-source.tf similarity index 100% rename from examples/resources/coder_parameter/resource.tf rename to examples/data-sources/coder_parameter/data-source.tf diff --git a/examples/resources/coder_workspace_tags/resource.tf b/examples/data-sources/coder_workspace_tags/data-source.tf similarity index 100% rename from examples/resources/coder_workspace_tags/resource.tf rename to examples/data-sources/coder_workspace_tags/data-source.tf diff --git a/provider/examples_test.go b/provider/examples_test.go index 6fa73d21..ab68954b 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -1,13 +1,13 @@ package provider_test import ( + "fmt" "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/stretchr/testify/require" - "github.com/coder/terraform-provider-coder/provider" ) @@ -22,19 +22,23 @@ func TestExamples(t *testing.T) { testDir := testDir t.Parallel() - resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, - Steps: []resource.TestStep{{ - Config: mustReadFile(t, "../examples/resources/"+testDir+"/resource.tf"), - }}, - }) + resourceTest(t, testDir) }) } } +func resourceTest(t *testing.T, testDir string) { + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: mustReadFile(t, fmt.Sprintf("../examples/data-sources/%s/data-source.tf", testDir)), + }}, + }) +} + func mustReadFile(t *testing.T, path string) string { content, err := os.ReadFile(path) require.NoError(t, err) From dd5f55c82a7dca0179eb45b1e38aea7c81948c88 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 26 Jun 2024 11:09:31 +0200 Subject: [PATCH 081/173] feat: include deprecation message in docs (#245) --- Makefile | 1 + docs/data-sources/workspace.md | 14 +++--- docs/index.md | 2 +- docs/resources/agent.md | 6 +-- docs/resources/app.md | 4 +- scripts/docsgen/main.go | 89 ++++++++++++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 scripts/docsgen/main.go diff --git a/Makefile b/Makefile index 43c93a83..38a9a69d 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ fmt: gen: go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@latest + go run ./scripts/docsgen/... build: terraform-provider-coder diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 2a813722..e9de5889 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -30,13 +30,13 @@ resource "kubernetes_pod" "dev" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `name` (String) Name of the workspace. -- `owner` (String, Deprecated) Username of the workspace owner. -- `owner_email` (String, Deprecated) Email address of the workspace owner. -- `owner_groups` (List of String, Deprecated) List of groups the workspace owner belongs to. -- `owner_id` (String, Deprecated) UUID of the workspace owner. -- `owner_name` (String, Deprecated) Name of the workspace owner. -- `owner_oidc_access_token` (String, Deprecated) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String, Deprecated) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. +- `owner` (String, Deprecated: Use `coder_workspace_owner.name` instead.) Username of the workspace owner. +- `owner_email` (String, Deprecated: Use `coder_workspace_owner.email` instead.) Email address of the workspace owner. +- `owner_groups` (List of String, Deprecated: Use `coder_workspace_owner.groups` instead.) List of groups the workspace owner belongs to. +- `owner_id` (String, Deprecated: Use `coder_workspace_owner.id` instead.) UUID of the workspace owner. +- `owner_name` (String, Deprecated: Use `coder_workspace_owner.full_name` instead.) Name of the workspace owner. +- `owner_oidc_access_token` (String, Deprecated: Use `coder_workspace_owner.oidc_access_token` instead.) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. +- `owner_session_token` (String, Deprecated: Use `coder_workspace_owner.session_token` instead.) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. diff --git a/docs/index.md b/docs/index.md index 13bf6b44..84843dec 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,5 +62,5 @@ resource "google_compute_instance" "dev" { ### Optional -- `feature_use_managed_variables` (Boolean, Deprecated) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. +- `feature_use_managed_variables` (Boolean, Deprecated: Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. - `url` (String) The URL to access Coder. \ No newline at end of file diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 68963947..d20374d0 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -76,15 +76,15 @@ resource "kubernetes_pod" "dev" { - `dir` (String) The starting directory when a user creates a shell session. Defaults to $HOME. - `display_apps` (Block Set, Max: 1) The list of built-in apps to display in the agent bar. (see [below for nested schema](#nestedblock--display_apps)) - `env` (Map of String) A mapping of environment variables to set inside the workspace. -- `login_before_ready` (Boolean, Deprecated) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. +- `login_before_ready` (Boolean, Deprecated: Configure startup_script_behavior instead. This attribute will be removed in a future version of the provider.) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. - `order` (Number) The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order). - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true. -- `shutdown_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. +- `shutdown_script_timeout` (Number, Deprecated: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true. - `startup_script_behavior` (String) This option sets the behavior of the "startup_script". When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. This option is an alias for defining a "coder_script" resource with "start_blocks_login" set to true (blocking). -- `startup_script_timeout` (Number, Deprecated) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. +- `startup_script_timeout` (Number, Deprecated: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. ### Read-Only diff --git a/docs/resources/app.md b/docs/resources/app.md index aec85255..e9ca7b2f 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -64,9 +64,9 @@ resource "coder_app" "vim" { - `external` (Boolean) Specifies whether "url" is opened on the client machine instead of proxied through the workspace. - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. -- `name` (String, Deprecated) A display name to identify the app. +- `name` (String, Deprecated: `name` on apps is deprecated, use `display_name` instead) A display name to identify the app. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). -- `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. +- `relative_path` (Boolean, Deprecated: `relative_path` on apps is deprecated, use `subdomain` instead.) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. - `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false. - `url` (String) An external url if "external=true" or a URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both. diff --git a/scripts/docsgen/main.go b/scripts/docsgen/main.go new file mode 100644 index 00000000..90244ccd --- /dev/null +++ b/scripts/docsgen/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "bytes" + "fmt" + "log" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/coder/terraform-provider-coder/provider" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "golang.org/x/xerrors" +) + +// This script patches Markdown docs generated by `terraform-plugin-docs` to expose the original deprecation message. + +const docsDir = "docs" // FIXME expose as flag? + +var reDeprecatedProperty = regexp.MustCompile("`([^`]+)` \\(([^,\\)]+), Deprecated\\) ([^\n]+)") + +func main() { + p := provider.New() + err := exposeDeprecationMessage(p) + if err != nil { + log.Fatal(err) + } +} + +func exposeDeprecationMessage(p *schema.Provider) error { + // Patch data-sources + for dataSourceName, dataSource := range p.DataSourcesMap { + docFile := filepath.Join(docsDir, "data-sources", strings.Replace(dataSourceName, "coder_", "", 1)+".md") + + err := adjustDocFile(docFile, dataSource.Schema) + if err != nil { + return xerrors.Errorf("unable to adjust data-source doc file (data-source: %s): %w", dataSourceName, err) + } + } + + // Patch resources + for resourceName, resource := range p.ResourcesMap { + docFile := filepath.Join(docsDir, "resources", strings.Replace(resourceName, "coder_", "", 1)+".md") + + err := adjustDocFile(docFile, resource.Schema) + if err != nil { + return xerrors.Errorf("unable to adjust resource doc file (resource: %s): %w", resourceName, err) + } + } + + // Patch index + docFile := filepath.Join(docsDir, "index.md") + err := adjustDocFile(docFile, p.Schema) + if err != nil { + return xerrors.Errorf("unable to adjust index doc file: %w", err) + } + return nil +} + +func adjustDocFile(docPath string, schemas map[string]*schema.Schema) error { + doc, err := os.ReadFile(docPath) + if err != nil { + return xerrors.Errorf("can't read the source doc file: %w", err) + } + + result := writeDeprecationMessage(doc, schemas) + + err = os.WriteFile(docPath, result, 0644) + if err != nil { + return xerrors.Errorf("can't write modified doc file: %w", err) + } + return nil +} + +func writeDeprecationMessage(doc []byte, schemas map[string]*schema.Schema) []byte { + return reDeprecatedProperty.ReplaceAllFunc(doc, func(m []byte) []byte { + matches := reDeprecatedProperty.FindSubmatch(m) + propertyName := matches[1] + description := matches[3] + + sch := schemas[string(propertyName)] + if string(description) != sch.Description { + log.Printf("warn: same property name `%s` but description does not match, most likely a different property", propertyName) + return m + } + return bytes.Replace(m, []byte("Deprecated"), []byte(fmt.Sprintf("Deprecated: %s", sch.Deprecated)), 1) + }) +} From 9f66e78cd771cfff45413378367dda45d98ea2fe Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 27 Jun 2024 11:06:29 +0200 Subject: [PATCH 082/173] feat: require environment variables (#246) --- provider/helpers/env.go | 6 ++++++ provider/workspace.go | 15 ++++++++++++--- provider/workspace_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/provider/helpers/env.go b/provider/helpers/env.go index b1007820..6ffab3f6 100644 --- a/provider/helpers/env.go +++ b/provider/helpers/env.go @@ -6,7 +6,13 @@ import ( ) // RequireEnv requires environment variable to be present. +// The constraint can be verified only during execution of the workspace build +// (determined with env `CODER_WORKSPACE_BUILD_ID`). func RequireEnv(name string) (string, error) { + if os.Getenv("CODER_WORKSPACE_BUILD_ID") == "" { + return os.Getenv(name), nil + } + val := os.Getenv(name) if val == "" { return "", fmt.Errorf("%s is required", name) diff --git a/provider/workspace.go b/provider/workspace.go index f06e9e1e..d8bfd3a5 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -62,13 +62,22 @@ func workspaceDataSource() *schema.Resource { id := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_ID", uuid.NewString()) rd.SetId(id) - templateID := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_ID") // FIXME switch to `helpers.RequireEnv(...)` + templateID, err := helpers.RequireEnv("CODER_WORKSPACE_TEMPLATE_ID") + if err != nil { + return diag.Errorf("template ID is missing: %s", err.Error()) + } _ = rd.Set("template_id", templateID) - templateName := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_NAME") // FIXME switch to `helpers.RequireEnv(...)` + templateName, err := helpers.RequireEnv("CODER_WORKSPACE_TEMPLATE_NAME") + if err != nil { + return diag.Errorf("template name is missing: %s", err.Error()) + } _ = rd.Set("template_name", templateName) - templateVersion := helpers.OptionalEnv("CODER_WORKSPACE_TEMPLATE_VERSION") // FIXME switch to `helpers.RequireEnv(...)` + templateVersion, err := helpers.RequireEnv("CODER_WORKSPACE_TEMPLATE_VERSION") + if err != nil { + return diag.Errorf("template version is missing: %s", err.Error()) + } _ = rd.Set("template_version", templateVersion) config, valid := i.(config) diff --git a/provider/workspace_test.go b/provider/workspace_test.go index d285b30c..e53f30d4 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -1,6 +1,7 @@ package provider_test import ( + "regexp" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -102,3 +103,34 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { }}, }) } + +func TestWorkspace_MissingTemplateName(t *testing.T) { + t.Setenv("CODER_WORKSPACE_BUILD_ID", "1") // Let's pretend this is a workspace build + + t.Setenv("CODER_WORKSPACE_OWNER", "owner123") + t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") + t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") + t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") + t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") + t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) + t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") + t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") + // CODER_WORKSPACE_TEMPLATE_NAME is missing + t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") + + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com:8080" + } + data "coder_workspace" "me" { + }`, + ExpectError: regexp.MustCompile("CODER_WORKSPACE_TEMPLATE_NAME is required"), + }}, + }) +} From e6ba29a45b948c117462d2509f1c680b22af294e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 27 Jun 2024 10:42:36 +0100 Subject: [PATCH 083/173] chore: improve integration test compatibility with older Coder versions (#247) Previously, testing with coder versions older than 2.7 would fail due to the template push command not creating the template automatically. Also, improves logic around pulling the image if it does not exist locally. --- go.mod | 2 ++ go.sum | 4 +++ integration/integration_test.go | 63 +++++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 625aae19..b5e26e56 100644 --- a/go.mod +++ b/go.mod @@ -76,6 +76,8 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect diff --git a/go.sum b/go.sum index d07d5ff3..047612ff 100644 --- a/go.sum +++ b/go.sum @@ -252,9 +252,13 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/integration/integration_test.go b/integration/integration_test.go index cf58b99e..49b36456 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -21,6 +21,8 @@ import ( "github.com/docker/docker/pkg/stdcopy" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" + "golang.org/x/mod/semver" ) // TestIntegration performs an integration test against an ephemeral Coder deployment. @@ -37,6 +39,16 @@ func TestIntegration(t *testing.T) { t.Skip("Skipping integration tests during tf acceptance tests") } + coderImg := os.Getenv("CODER_IMAGE") + if coderImg == "" { + coderImg = "ghcr.io/coder/coder" + } + + coderVersion := os.Getenv("CODER_VERSION") + if coderVersion == "" { + coderVersion = "latest" + } + timeoutStr := os.Getenv("TIMEOUT_MINS") if timeoutStr == "" { timeoutStr = "10" @@ -88,9 +100,17 @@ func TestIntegration(t *testing.T) { } { t.Run(tt.name, func(t *testing.T) { // Given: we have an existing Coder deployment running locally - ctrID := setup(ctx, t, tt.name) + ctrID := setup(ctx, t, tt.name, coderImg, coderVersion) // Import named template - _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates push %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, tt.name, tt.name, tt.name)) + + // NOTE: Template create command was deprecated after this version + // ref: https://github.com/coder/coder/pull/11390 + templateCreateCmd := "push" + if semver.Compare(coderVersion, "v2.7.0") < 1 { + t.Logf("using now-deprecated templates create command for older coder version") + templateCreateCmd = "create" + } + _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates %s %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, templateCreateCmd, tt.name, tt.name, tt.name)) require.Equal(t, 0, rc) // Create a workspace _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s --yes`, tt.name, tt.name)) @@ -105,7 +125,7 @@ func TestIntegration(t *testing.T) { } } -func setup(ctx context.Context, t *testing.T, name string) string { +func setup(ctx context.Context, t *testing.T, name, coderImg, coderVersion string) string { var ( // For this test to work, we pass in a custom terraformrc to use // the locally built version of the provider. @@ -118,16 +138,6 @@ func setup(ctx context.Context, t *testing.T, name string) string { localURL = "http://localhost:3000" ) - coderImg := os.Getenv("CODER_IMAGE") - if coderImg == "" { - coderImg = "ghcr.io/coder/coder" - } - - coderVersion := os.Getenv("CODER_VERSION") - if coderVersion == "" { - coderVersion = "latest" - } - t.Logf("using coder image %s:%s", coderImg, coderVersion) // Ensure the binary is built @@ -151,11 +161,7 @@ func setup(ctx context.Context, t *testing.T, name string) string { // Ensure the image is available locally. refStr := coderImg + ":" + coderVersion - t.Logf("ensuring image %q", refStr) - resp, err := cli.ImagePull(ctx, refStr, image.PullOptions{}) - require.NoError(t, err) - _, err = io.ReadAll(resp) - require.NoError(t, err) + ensureImage(ctx, t, cli, refStr) // Stand up a temporary Coder instance ctr, err := cli.ContainerCreate(ctx, &container.Config{ @@ -213,6 +219,25 @@ func setup(ctx context.Context, t *testing.T, name string) string { return ctr.ID } +func ensureImage(ctx context.Context, t *testing.T, cli *client.Client, ref string) { + t.Helper() + + t.Logf("ensuring image %q", ref) + images, err := cli.ImageList(ctx, image.ListOptions{}) + require.NoError(t, err, "list images") + for _, img := range images { + if slices.Contains(img.RepoTags, ref) { + t.Logf("image %q found locally, not pulling", ref) + return + } + } + t.Logf("image %s not found locally, attempting to pull", ref) + resp, err := cli.ImagePull(ctx, ref, image.PullOptions{}) + require.NoError(t, err) + _, err = io.ReadAll(resp) + require.NoError(t, err) +} + // execContainer executes the given command in the given container and returns // the output and the exit code of the command. func execContainer(ctx context.Context, t *testing.T, containerID, command string) (string, int) { @@ -249,7 +274,7 @@ func assertOutput(t *testing.T, expected, actual map[string]string) { for expectedKey, expectedValExpr := range expected { actualVal := actual[expectedKey] - assert.Regexp(t, expectedValExpr, actualVal) + assert.Regexp(t, expectedValExpr, actualVal, "output key %q does not have expected value", expectedKey) } for actualKey := range actual { _, ok := expected[actualKey] From 60401e6865b69ee49374c9800b561e58dd2dadd7 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 27 Jun 2024 12:15:14 +0100 Subject: [PATCH 084/173] ci: run integration test against mainline and stable versions (#248) - Adds `scripts/coderversion` to fetch stable and mainline versions - Adds `minVersion` constraint to integration tests - Runs integration tests against both stable and mainline versions - Adds separate integration test for fields introduced in v2.12.0 --- .github/workflows/test.yml | 14 +++- go.mod | 6 +- go.sum | 4 + integration/integration_test.go | 37 ++++++++- integration/test-data-source/main.tf | 9 --- integration/workspace-owner/main.tf | 65 ++++++++++++++++ scripts/coderversion/main.go | 109 +++++++++++++++++++++++++++ 7 files changed, 228 insertions(+), 16 deletions(-) create mode 100644 integration/workspace-owner/main.tf create mode 100644 scripts/coderversion/main.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 217c065f..f17d1c10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,13 +38,21 @@ jobs: run: | go build -v . - - name: Run integration test + - name: Run integration test (mainline) timeout-minutes: 10 env: CODER_IMAGE: "ghcr.io/coder/coder" - CODER_VERSION: "latest" run: | - go test -v ./integration + source <(go run ./scripts/coderversion) + CODER_VERSION="${CODER_MAINLINE_VERSION}" go test -v ./integration + + - name: Run integration test (stable) + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder" + run: | + source <(go run ./scripts/coderversion) + CODER_VERSION="${CODER_STABLE_VERSION}" go test -v ./integration # run acceptance tests in a matrix with Terraform core versions test: diff --git a/go.mod b/go.mod index b5e26e56..7e8aebe9 100644 --- a/go.mod +++ b/go.mod @@ -9,13 +9,17 @@ require ( github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 + github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.9.0 + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 + golang.org/x/mod v0.18.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) require ( + github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect @@ -76,8 +80,6 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect diff --git a/go.sum b/go.sum index 047612ff..79ed9f85 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= @@ -147,6 +149,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/masterminds/semver v1.5.0 h1:hTxJTTY7tjvnWMrl08O6u3G6BLlKVwxSz01lVac9P8U= +github.com/masterminds/semver v1.5.0/go.mod h1:s7KNT9fnd7edGzwwP7RBX4H0v/CYd5qdOLfkL1V75yg= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= diff --git a/integration/integration_test.go b/integration/integration_test.go index 49b36456..75b35d20 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -57,15 +57,19 @@ func TestIntegration(t *testing.T) { require.NoError(t, err, "invalid value specified for timeout") ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutMins)*time.Minute) t.Cleanup(cancel) + ctrID := setup(ctx, t, t.Name(), coderImg, coderVersion) for _, tt := range []struct { // Name of the folder under `integration/` containing a test template name string + // Minimum coder version for which to run this test + minVersion string // map of string to regex to be passed to assertOutput() expectedOutput map[string]string }{ { - name: "test-data-source", + name: "test-data-source", + minVersion: "v0.0.0", expectedOutput: map[string]string{ "provisioner.arch": runtime.GOARCH, "provisioner.id": `[a-zA-Z0-9-]+`, @@ -86,6 +90,31 @@ func TestIntegration(t *testing.T) { "workspace.template_name": `test-data-source`, "workspace.template_version": `.+`, "workspace.transition": `start`, + }, + }, + { + name: "workspace-owner", + minVersion: "v2.12.0", + expectedOutput: map[string]string{ + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": ``, + "workspace.owner": `testing`, + "workspace.owner_email": `testing@coder\.com`, + "workspace.owner_groups": `\[\]`, + "workspace.owner_id": `[a-zA-Z0-9]+`, + "workspace.owner_name": `default`, + "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration + "workspace.owner_session_token": `[a-zA-Z0-9-]+`, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `workspace-owner`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, "workspace_owner.email": `testing@coder\.com`, "workspace_owner.full_name": `default`, "workspace_owner.groups": `\[\]`, @@ -98,9 +127,13 @@ func TestIntegration(t *testing.T) { }, }, } { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if coderVersion != "latest" && semver.Compare(coderVersion, tt.minVersion) < 0 { + t.Skipf("skipping due to CODER_VERSION %q < minVersion %q", coderVersion, tt.minVersion) + } // Given: we have an existing Coder deployment running locally - ctrID := setup(ctx, t, tt.name, coderImg, coderVersion) // Import named template // NOTE: Template create command was deprecated after this version diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 580592cb..838125a0 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -38,15 +38,6 @@ locals { "workspace.template_name" : data.coder_workspace.me.template_name, "workspace.template_version" : data.coder_workspace.me.template_version, "workspace.transition" : data.coder_workspace.me.transition, - "workspace_owner.email" : data.coder_workspace_owner.me.email, - "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, - "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), - "workspace_owner.id" : data.coder_workspace_owner.me.id, - "workspace_owner.name" : data.coder_workspace_owner.me.name, - "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, - "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, - "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, - "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, } } diff --git a/integration/workspace-owner/main.tf b/integration/workspace-owner/main.tf new file mode 100644 index 00000000..580592cb --- /dev/null +++ b/integration/workspace-owner/main.tf @@ -0,0 +1,65 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +// TODO: test coder_external_auth and coder_git_auth +// data coder_external_auth "me" {} +// data coder_git_auth "me" {} +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +locals { + # NOTE: these must all be strings in the output + output = { + "provisioner.arch" : data.coder_provisioner.me.arch, + "provisioner.id" : data.coder_provisioner.me.id, + "provisioner.os" : data.coder_provisioner.me.os, + "workspace.access_port" : tostring(data.coder_workspace.me.access_port), + "workspace.access_url" : data.coder_workspace.me.access_url, + "workspace.id" : data.coder_workspace.me.id, + "workspace.name" : data.coder_workspace.me.name, + "workspace.owner" : data.coder_workspace.me.owner, + "workspace.owner_email" : data.coder_workspace.me.owner_email, + "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), + "workspace.owner_id" : data.coder_workspace.me.owner_id, + "workspace.owner_name" : data.coder_workspace.me.owner_name, + "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, + "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, + "workspace.start_count" : tostring(data.coder_workspace.me.start_count), + "workspace.template_id" : data.coder_workspace.me.template_id, + "workspace.template_name" : data.coder_workspace.me.template_name, + "workspace.template_version" : data.coder_workspace.me.template_version, + "workspace.transition" : data.coder_workspace.me.transition, + "workspace_owner.email" : data.coder_workspace_owner.me.email, + "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, + "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), + "workspace_owner.id" : data.coder_workspace_owner.me.id, + "workspace_owner.name" : data.coder_workspace_owner.me.name, + "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, + "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, + "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, + "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} diff --git a/scripts/coderversion/main.go b/scripts/coderversion/main.go new file mode 100644 index 00000000..fa2c1705 --- /dev/null +++ b/scripts/coderversion/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" + "os" + + "github.com/masterminds/semver" +) + +func main() { + releases := fetchReleases() + + mainlineVer := semver.MustParse("v0.0.0") + for _, rel := range releases { + if rel == "" { + debug("ignoring untagged version %s\n", rel) + continue + } + + ver, err := semver.NewVersion(rel) + if err != nil { + debug("skipping invalid version %s\n", rel) + } + + if ver.Compare(mainlineVer) > 0 { + mainlineVer = ver + continue + } + } + + mainline := fmt.Sprintf("v%d.%d.%d", mainlineVer.Major(), mainlineVer.Minor(), mainlineVer.Patch()) + _, _ = fmt.Fprintf(os.Stdout, "CODER_MAINLINE_VERSION=%q\n", mainline) + + expectedStableMinor := mainlineVer.Minor() - 1 + if expectedStableMinor < 0 { + expectedStableMinor = 0 + } + debug("expected stable minor: %d\n", expectedStableMinor) + stableVer := semver.MustParse("v0.0.0") + for _, rel := range releases { + debug("check version %s\n", rel) + if rel == "" { + debug("ignoring untagged version %s\n", rel) + continue + } + + ver, err := semver.NewVersion(rel) + if err != nil { + debug("skipping invalid version %s\n", rel) + } + + if ver.Minor() != expectedStableMinor { + debug("skipping version %s\n", rel) + continue + } + + if ver.Compare(stableVer) > 0 { + stableVer = ver + continue + } + } + + stable := fmt.Sprintf("v%d.%d.%d", stableVer.Major(), stableVer.Minor(), stableVer.Patch()) + _, _ = fmt.Fprintf(os.Stdout, "CODER_STABLE_VERSION=%q\n", stable) +} + +type release struct { + TagName string `json:"tag_name"` +} + +const releasesURL = "https://api.github.com/repos/coder/coder/releases" + +// fetchReleases fetches the releases of coder/coder +// this is done directly via JSON API to avoid pulling in the entire +// github client +func fetchReleases() []string { + resp, err := http.Get(releasesURL) + if err != nil { + fatal("get releases: %w", err) + } + defer resp.Body.Close() + + var releases []release + if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil { + fatal("parse releases: %w", err) + } + + var ss []string + for _, rel := range releases { + if rel.TagName != "" { + ss = append(ss, rel.TagName) + + } + } + return ss +} + +func debug(format string, args ...any) { + if _, ok := os.LookupEnv("VERBOSE"); ok { + _, _ = fmt.Fprintf(os.Stderr, format, args...) + } +} + +func fatal(format string, args ...any) { + _, _ = fmt.Fprintf(os.Stderr, format, args...) + os.Exit(1) +} From 35e6ac88f9b86dc8e141a67f3e68add3ca6bad14 Mon Sep 17 00:00:00 2001 From: Stephen Kirby <58410745+stirby@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:16:51 -0500 Subject: [PATCH 085/173] docs: add missing code examples (#249) * coder_env code example * added coder_script example * updated coder_script description to note parallelism * short coder_external_auth example * added external auth link, make gen * fixed icon link for coder_parameter * coder_provisioner example * fixed inline links for provisioner * added coder_workspace_owner examples --- docs/data-sources/external_auth.md | 18 +++++- docs/data-sources/parameter.md | 2 +- docs/data-sources/provisioner.md | 24 +++++++- docs/data-sources/workspace_owner.md | 31 ++++++++++ docs/resources/env.md | 24 +++++++- docs/resources/script.md | 59 ++++++++++++++++++- .../coder_external_auth/data-source.tf | 11 ++++ .../coder_provisioner/data-source.tf | 17 ++++++ .../coder_workspace_owner/data-source.tf | 28 +++++++++ examples/resources/coder_env/resource.tf | 19 ++++++ examples/resources/coder_script/resource.tf | 52 ++++++++++++++++ provider/externalauth.go | 2 +- provider/parameter.go | 2 +- provider/provisioner.go | 4 +- provider/script.go | 2 +- 15 files changed, 282 insertions(+), 13 deletions(-) create mode 100644 examples/data-sources/coder_external_auth/data-source.tf create mode 100644 examples/data-sources/coder_provisioner/data-source.tf create mode 100644 examples/data-sources/coder_workspace_owner/data-source.tf create mode 100644 examples/resources/coder_env/resource.tf create mode 100644 examples/resources/coder_script/resource.tf diff --git a/docs/data-sources/external_auth.md b/docs/data-sources/external_auth.md index af4df43b..e4089f24 100644 --- a/docs/data-sources/external_auth.md +++ b/docs/data-sources/external_auth.md @@ -3,14 +3,28 @@ page_title: "coder_external_auth Data Source - terraform-provider-coder" subcategory: "" description: |- - Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc) + Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services https://coder.com/docs/admin/external-auth in a workspace. (e.g. Google Cloud, Github, Docker, etc.) --- # coder_external_auth (Data Source) -Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc) +Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to [pre-authenticate external services](https://coder.com/docs/admin/external-auth) in a workspace. (e.g. Google Cloud, Github, Docker, etc.) +## Example Usage +```terraform +provider "coder" {} + + +data "coder_external_auth" "github" { + id = "github" +} + +data "coder_external_auth" "azure-identity" { + id = "azure-identiy" + optional = true +} +``` ## Schema diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 9c6a11f5..178c6d9d 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -145,7 +145,7 @@ data "coder_parameter" "home_volume_size" { - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. - `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! - `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). diff --git a/docs/data-sources/provisioner.md b/docs/data-sources/provisioner.md index 4316aeea..ba930a2a 100644 --- a/docs/data-sources/provisioner.md +++ b/docs/data-sources/provisioner.md @@ -10,13 +10,33 @@ description: |- Use this data source to get information about the Coder provisioner. +## Example Usage +```terraform +provider "coder" {} + +data "coder_provisioner" "dev" {} + +data "coder_workspace" "dev" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.dev.arch + os = data.coder_provisioner.dev.os + dir = "/workspace" + display_apps { + vscode = true + vscode_insiders = false + web_terminal = true + ssh_helper = false + } +} +``` ## Schema ### Read-Only -- `arch` (String) The architecture of the host. This exposes `runtime.GOARCH` (see https://pkg.go.dev/runtime#pkg-constants). +- `arch` (String) The architecture of the host. This exposes `runtime.GOARCH` (see [Go constants](https://pkg.go.dev/runtime#pkg-constants)). - `id` (String) The ID of this resource. -- `os` (String) The operating system of the host. This exposes `runtime.GOOS` (see https://pkg.go.dev/runtime#pkg-constants). +- `os` (String) The operating system of the host. This exposes `runtime.GOOS` (see [Go constants](https://pkg.go.dev/runtime#pkg-constants)). diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index 646b1340..0deff622 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -10,7 +10,38 @@ description: |- Use this data source to fetch information about the workspace owner. +## Example Usage +```terraform +provider "coder" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = local.repo_dir + env = { + OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, + } +} + +# Add git credentials from coder_workspace_owner +resource "coder_env" "git_author_name" { + agent_id = coder_agent.agent_id + name = "GIT_AUTHOR_NAME" + value = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) +} + +resource "coder_env" "git_author_email" { + agent_id = var.agent_id + name = "GIT_AUTHOR_EMAIL" + value = data.coder_workspace_owner.me.email + count = data.coder_workspace_owner.me.email != "" ? 1 : 0 +} +``` ## Schema diff --git a/docs/resources/env.md b/docs/resources/env.md index b948bad9..3531335c 100644 --- a/docs/resources/env.md +++ b/docs/resources/env.md @@ -10,7 +10,29 @@ description: |- Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource. - +## Example Usage + +```terraform +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_env" "welcome_message" { + agent_id = coder_agent.dev.id + name = "WELCOME_MESSAGE" + value = "Welcome to your Coder workspace!" +} + +resource "coder_env" "internal_api_url" { + agent_id = coder_agent.dev.id + name = "INTERNAL_API_URL" + value = "https://api.internal.company.com/v1" +} +``` ## Schema diff --git a/docs/resources/script.md b/docs/resources/script.md index a16b39f5..d4d5dd9f 100644 --- a/docs/resources/script.md +++ b/docs/resources/script.md @@ -3,14 +3,69 @@ page_title: "coder_script Resource - terraform-provider-coder" subcategory: "" description: |- - Use this resource to run a script from an agent. + Use this resource to run a script from an agent. When multiple scripts are assigned to the same agent, they are executed in parallel. --- # coder_script (Resource) -Use this resource to run a script from an agent. +Use this resource to run a script from an agent. When multiple scripts are assigned to the same agent, they are executed in parallel. +## Example Usage +```terraform +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_script" "dotfiles" { + agent_id = coder_agent.dev.agent_id + display_name = "Dotfiles" + icon = "/icon/dotfiles.svg" + run_on_start = true + script = templatefile("~/get_dotfiles.sh", { + DOTFILES_URI : var.dotfiles_uri, + DOTFILES_USER : var.dotfiles_user + }) +} + +resource "coder_script" "code-server" { + agent_id = coder_agent.dev.agent_id + display_name = "code-server" + icon = "/icon/code.svg" + run_on_start = true + start_blocks_login = true + script = templatefile("./install-code-server.sh", { + LOG_PATH : "/tmp/code-server.log" + }) +} + +resource "coder_script" "nightly_sleep_reminder" { + agent_id = coder_agent.dev.agent_id + display_name = "Nightly update" + icon = "/icon/database.svg" + cron = "0 22 * * *" + script = </tmp/pid.log 2>&1 & + EOF +} +``` ## Schema diff --git a/examples/data-sources/coder_external_auth/data-source.tf b/examples/data-sources/coder_external_auth/data-source.tf new file mode 100644 index 00000000..330ff216 --- /dev/null +++ b/examples/data-sources/coder_external_auth/data-source.tf @@ -0,0 +1,11 @@ +provider "coder" {} + + +data "coder_external_auth" "github" { + id = "github" +} + +data "coder_external_auth" "azure-identity" { + id = "azure-identiy" + optional = true +} diff --git a/examples/data-sources/coder_provisioner/data-source.tf b/examples/data-sources/coder_provisioner/data-source.tf new file mode 100644 index 00000000..a94823ed --- /dev/null +++ b/examples/data-sources/coder_provisioner/data-source.tf @@ -0,0 +1,17 @@ +provider "coder" {} + +data "coder_provisioner" "dev" {} + +data "coder_workspace" "dev" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.dev.arch + os = data.coder_provisioner.dev.os + dir = "/workspace" + display_apps { + vscode = true + vscode_insiders = false + web_terminal = true + ssh_helper = false + } +} \ No newline at end of file diff --git a/examples/data-sources/coder_workspace_owner/data-source.tf b/examples/data-sources/coder_workspace_owner/data-source.tf new file mode 100644 index 00000000..fc27db6c --- /dev/null +++ b/examples/data-sources/coder_workspace_owner/data-source.tf @@ -0,0 +1,28 @@ +provider "coder" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = local.repo_dir + env = { + OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, + } +} + +# Add git credentials from coder_workspace_owner +resource "coder_env" "git_author_name" { + agent_id = coder_agent.agent_id + name = "GIT_AUTHOR_NAME" + value = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) +} + +resource "coder_env" "git_author_email" { + agent_id = var.agent_id + name = "GIT_AUTHOR_EMAIL" + value = data.coder_workspace_owner.me.email + count = data.coder_workspace_owner.me.email != "" ? 1 : 0 +} \ No newline at end of file diff --git a/examples/resources/coder_env/resource.tf b/examples/resources/coder_env/resource.tf new file mode 100644 index 00000000..9f8e28f2 --- /dev/null +++ b/examples/resources/coder_env/resource.tf @@ -0,0 +1,19 @@ +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_env" "welcome_message" { + agent_id = coder_agent.dev.id + name = "WELCOME_MESSAGE" + value = "Welcome to your Coder workspace!" +} + +resource "coder_env" "internal_api_url" { + agent_id = coder_agent.dev.id + name = "INTERNAL_API_URL" + value = "https://api.internal.company.com/v1" +} \ No newline at end of file diff --git a/examples/resources/coder_script/resource.tf b/examples/resources/coder_script/resource.tf new file mode 100644 index 00000000..b7fced38 --- /dev/null +++ b/examples/resources/coder_script/resource.tf @@ -0,0 +1,52 @@ +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_script" "dotfiles" { + agent_id = coder_agent.dev.agent_id + display_name = "Dotfiles" + icon = "/icon/dotfiles.svg" + run_on_start = true + script = templatefile("~/get_dotfiles.sh", { + DOTFILES_URI : var.dotfiles_uri, + DOTFILES_USER : var.dotfiles_user + }) +} + +resource "coder_script" "code-server" { + agent_id = coder_agent.dev.agent_id + display_name = "code-server" + icon = "/icon/code.svg" + run_on_start = true + start_blocks_login = true + script = templatefile("./install-code-server.sh", { + LOG_PATH : "/tmp/code-server.log" + }) +} + +resource "coder_script" "nightly_sleep_reminder" { + agent_id = coder_agent.dev.agent_id + display_name = "Nightly update" + icon = "/icon/database.svg" + cron = "0 22 * * *" + script = </tmp/pid.log 2>&1 & + EOF +} \ No newline at end of file diff --git a/provider/externalauth.go b/provider/externalauth.go index 13c85fab..a11a67c4 100644 --- a/provider/externalauth.go +++ b/provider/externalauth.go @@ -15,7 +15,7 @@ func externalAuthDataSource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, - Description: "Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to pre-authenticate external services in a workspace. (e.g. gcloud, gh, docker, etc)", + Description: "Use this data source to require users to authenticate with an external service prior to workspace creation. This can be used to [pre-authenticate external services](https://coder.com/docs/admin/external-auth) in a workspace. (e.g. Google Cloud, Github, Docker, etc.)", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { id, ok := rd.Get("id").(string) if !ok || id == "" { diff --git a/provider/parameter.go b/provider/parameter.go index d0f71dab..281537f6 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -220,7 +220,7 @@ func parameterDataSource() *schema.Resource { "icon": { Type: schema.TypeString, Description: "A URL to an icon that will display in the dashboard. View built-in " + - "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + + "icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " + "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", ForceNew: true, Optional: true, diff --git a/provider/provisioner.go b/provider/provisioner.go index 9d356798..49a40d21 100644 --- a/provider/provisioner.go +++ b/provider/provisioner.go @@ -29,12 +29,12 @@ func provisionerDataSource() *schema.Resource { "os": { Type: schema.TypeString, Computed: true, - Description: "The operating system of the host. This exposes `runtime.GOOS` (see https://pkg.go.dev/runtime#pkg-constants).", + Description: "The operating system of the host. This exposes `runtime.GOOS` (see [Go constants](https://pkg.go.dev/runtime#pkg-constants)).", }, "arch": { Type: schema.TypeString, Computed: true, - Description: "The architecture of the host. This exposes `runtime.GOARCH` (see https://pkg.go.dev/runtime#pkg-constants).", + Description: "The architecture of the host. This exposes `runtime.GOARCH` (see [Go constants](https://pkg.go.dev/runtime#pkg-constants)).", }, }, } diff --git a/provider/script.go b/provider/script.go index 1474dbd2..536a5732 100644 --- a/provider/script.go +++ b/provider/script.go @@ -17,7 +17,7 @@ func scriptResource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, - Description: "Use this resource to run a script from an agent.", + Description: "Use this resource to run a script from an agent. When multiple scripts are assigned to the same agent, they are executed in parallel.", CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) runOnStart, _ := rd.Get("run_on_start").(bool) From 7c884015ef0088005f3a61e8dd780d6f4a3b7a3b Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 2 Jul 2024 14:34:51 +0100 Subject: [PATCH 086/173] fix(scripts/coderversion): fix error-wrapping directive (#251) --- scripts/coderversion/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/coderversion/main.go b/scripts/coderversion/main.go index fa2c1705..b6f57d4b 100644 --- a/scripts/coderversion/main.go +++ b/scripts/coderversion/main.go @@ -78,13 +78,13 @@ const releasesURL = "https://api.github.com/repos/coder/coder/releases" func fetchReleases() []string { resp, err := http.Get(releasesURL) if err != nil { - fatal("get releases: %w", err) + fatal("get releases: %s", err.Error()) } defer resp.Body.Close() var releases []release if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil { - fatal("parse releases: %w", err) + fatal("parse releases: %s", err.Error()) } var ss []string From d2e2d968046dcb68e2e67a07f05a5dd61058cf65 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 3 Jul 2024 16:01:57 +0300 Subject: [PATCH 087/173] docs: improve docs by using code-styled markdown (#253) * docs: improve docs by using code-styled markdown * `make gen` * fixup! * make deprecated bold * fix tests * fix tests * more formatting * fixes * make better * add deprecation warning to `coder_git_auth` --- docs/data-sources/git_auth.md | 5 +++++ docs/data-sources/parameter.md | 8 ++++---- docs/data-sources/workspace.md | 18 ++++++++--------- docs/index.md | 2 +- docs/resources/agent.md | 26 ++++++++++++------------ docs/resources/agent_instance.md | 4 ++-- docs/resources/app.md | 20 +++++++++---------- docs/resources/env.md | 6 +++--- docs/resources/metadata.md | 8 ++++---- docs/resources/script.md | 4 ++-- provider/agent.go | 34 ++++++++++++++++---------------- provider/app.go | 34 ++++++++++++++++---------------- provider/env.go | 4 ++-- provider/gitauth.go | 2 +- provider/metadata.go | 10 +++++----- provider/parameter.go | 10 +++++----- provider/script.go | 10 +++++----- provider/script_test.go | 4 ++-- provider/workspace.go | 4 ++-- scripts/docsgen/main.go | 2 +- 20 files changed, 110 insertions(+), 105 deletions(-) diff --git a/docs/data-sources/git_auth.md b/docs/data-sources/git_auth.md index fe64805e..e665aeb1 100644 --- a/docs/data-sources/git_auth.md +++ b/docs/data-sources/git_auth.md @@ -3,11 +3,16 @@ page_title: "coder_git_auth Data Source - terraform-provider-coder" subcategory: "" description: |- + ~> Deprecated + Use the coder_external_auth data source instead. Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated git clone in startup scripts. --- # coder_git_auth (Data Source) +~> **Deprecated** +Use the `coder_external_auth` data source instead. + Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts. ## Example Usage diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 178c6d9d..f40a9c83 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -145,11 +145,11 @@ data "coder_parameter" "home_volume_size" { - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. - `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! -- `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) +- `option` (Block List, Max: 64) Each `option` block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). -- `type` (String) The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)". +- `type` (String) The type of this parameter. Must be one of: `"number"`, `"string"`, `"bool"`, or `"list(string)"`. - `validation` (Block List, Max: 1) Validate the input of a parameter. (see [below for nested schema](#nestedblock--validation)) ### Read-Only @@ -169,7 +169,7 @@ Required: Optional: - `description` (String) Describe what selecting this value does. -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index e9de5889..8b824c37 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -30,15 +30,15 @@ resource "kubernetes_pod" "dev" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `name` (String) Name of the workspace. -- `owner` (String, Deprecated: Use `coder_workspace_owner.name` instead.) Username of the workspace owner. -- `owner_email` (String, Deprecated: Use `coder_workspace_owner.email` instead.) Email address of the workspace owner. -- `owner_groups` (List of String, Deprecated: Use `coder_workspace_owner.groups` instead.) List of groups the workspace owner belongs to. -- `owner_id` (String, Deprecated: Use `coder_workspace_owner.id` instead.) UUID of the workspace owner. -- `owner_name` (String, Deprecated: Use `coder_workspace_owner.full_name` instead.) Name of the workspace owner. -- `owner_oidc_access_token` (String, Deprecated: Use `coder_workspace_owner.oidc_access_token` instead.) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String, Deprecated: Use `coder_workspace_owner.session_token` instead.) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. -- `start_count` (Number) A computed count based on "transition" state. If "start", count will equal 1. +- `owner` (String, **Deprecated**: Use `coder_workspace_owner.name` instead.) Username of the workspace owner. +- `owner_email` (String, **Deprecated**: Use `coder_workspace_owner.email` instead.) Email address of the workspace owner. +- `owner_groups` (List of String, **Deprecated**: Use `coder_workspace_owner.groups` instead.) List of groups the workspace owner belongs to. +- `owner_id` (String, **Deprecated**: Use `coder_workspace_owner.id` instead.) UUID of the workspace owner. +- `owner_name` (String, **Deprecated**: Use `coder_workspace_owner.full_name` instead.) Name of the workspace owner. +- `owner_oidc_access_token` (String, **Deprecated**: Use `coder_workspace_owner.oidc_access_token` instead.) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. +- `owner_session_token` (String, **Deprecated**: Use `coder_workspace_owner.session_token` instead.) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. +- `start_count` (Number) A computed count based on `transition` state. If `start`, count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. - `template_version` (String) Version of the workspace's template. -- `transition` (String) Either "start" or "stop". Use this to start/stop resources with "count". +- `transition` (String) Either `start` or `stop`. Use this to start/stop resources with `count`. diff --git a/docs/index.md b/docs/index.md index 84843dec..a4dfd70e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,5 +62,5 @@ resource "google_compute_instance" "dev" { ### Optional -- `feature_use_managed_variables` (Boolean, Deprecated: Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. +- `feature_use_managed_variables` (Boolean, **Deprecated**: Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. - `url` (String) The URL to access Coder. \ No newline at end of file diff --git a/docs/resources/agent.md b/docs/resources/agent.md index d20374d0..e444d2d7 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -66,32 +66,32 @@ resource "kubernetes_pod" "dev" { ### Required -- `arch` (String) The architecture the agent will run on. Must be one of: "amd64", "armv7", "arm64". -- `os` (String) The operating system the agent will run on. Must be one of: "linux", "darwin", or "windows". +- `arch` (String) The architecture the agent will run on. Must be one of: `"amd64"`, `"armv7"`, `"arm64"`. +- `os` (String) The operating system the agent will run on. Must be one of: `"linux"`, `"darwin"`, or `"windows"`. ### Optional -- `auth` (String) The authentication type the agent will use. Must be one of: "token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity". +- `auth` (String) The authentication type the agent will use. Must be one of: `"token"`, `"google-instance-identity"`, `"aws-instance-identity"`, `"azure-instance-identity"`. - `connection_timeout` (Number) Time in seconds until the agent is marked as timed out when a connection with the server cannot be established. A value of zero never marks the agent as timed out. -- `dir` (String) The starting directory when a user creates a shell session. Defaults to $HOME. +- `dir` (String) The starting directory when a user creates a shell session. Defaults to `"$HOME"`. - `display_apps` (Block Set, Max: 1) The list of built-in apps to display in the agent bar. (see [below for nested schema](#nestedblock--display_apps)) - `env` (Map of String) A mapping of environment variables to set inside the workspace. -- `login_before_ready` (Boolean, Deprecated: Configure startup_script_behavior instead. This attribute will be removed in a future version of the provider.) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. -- `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) -- `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. +- `login_before_ready` (Boolean, **Deprecated**: Configure `startup_script_behavior` instead. This attribute will be removed in a future version of the provider.) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the `startup_script` is done and has exited. When enabled, users may see an incomplete workspace when logging in. +- `metadata` (Block List) Each `metadata` block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) +- `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be `"/etc/motd"`. - `order` (Number) The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order). -- `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true. -- `shutdown_script_timeout` (Number, Deprecated: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. -- `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true. -- `startup_script_behavior` (String) This option sets the behavior of the "startup_script". When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. This option is an alias for defining a "coder_script" resource with "start_blocks_login" set to true (blocking). -- `startup_script_timeout` (Number, Deprecated: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. +- `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a `coder_script` resource with `run_on_stop` set to `true`. +- `shutdown_script_timeout` (Number, **Deprecated**: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. +- `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a `coder_script` resource with `run_on_start` set to `true`. +- `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to `"blocking"`, the `startup_script` must exit before the workspace is ready. When set to `"non-blocking"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `"non-blocking"`, although `"blocking"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking). +- `startup_script_timeout` (Number, **Deprecated**: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. ### Read-Only - `id` (String) The ID of this resource. - `init_script` (String) Run this script on startup of an instance to initialize the agent. -- `token` (String, Sensitive) Set the environment variable "CODER_AGENT_TOKEN" with this token to authenticate an agent. +- `token` (String, Sensitive) Set the environment variable `CODER_AGENT_TOKEN` with this token to authenticate an agent. ### Nested Schema for `display_apps` diff --git a/docs/resources/agent_instance.md b/docs/resources/agent_instance.md index 6af2bb46..ec855b12 100644 --- a/docs/resources/agent_instance.md +++ b/docs/resources/agent_instance.md @@ -8,7 +8,7 @@ description: |- # coder_agent_instance (Resource) -Use this resource to associate an instance ID with an agent for zero-trust authentication. This association is done automatically for "google_compute_instance", "aws_instance", "azurerm_linux_virtual_machine", and "azurerm_windows_virtual_machine" resources. +Use this resource to associate an instance ID with an agent for zero-trust authentication. This association is done automatically for `"google_compute_instance"`, `"aws_instance"`, `"azurerm_linux_virtual_machine"`, and `"azurerm_windows_virtual_machine"` resources. ## Example Usage @@ -34,7 +34,7 @@ resource "coder_agent_instance" "dev" { ### Required -- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. - `instance_id` (String) The instance identifier of a provisioned resource. ### Read-Only diff --git a/docs/resources/app.md b/docs/resources/app.md index e9ca7b2f..f61ed799 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -54,22 +54,22 @@ resource "coder_app" "vim" { ### Required -- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. - `slug` (String) A hostname-friendly name for the app. This is used in URLs to access the app. May contain alphanumerics and hyphens. Cannot start/end with a hyphen or contain two consecutive hyphens. ### Optional -- `command` (String) A command to run in a terminal opening this app. In the web, this will open in a new tab. In the CLI, this will SSH and execute the command. Either "command" or "url" may be specified, but not both. +- `command` (String) A command to run in a terminal opening this app. In the web, this will open in a new tab. In the CLI, this will SSH and execute the command. Either `command` or `url` may be specified, but not both. - `display_name` (String) A display name to identify the app. Defaults to the slug. -- `external` (Boolean) Specifies whether "url" is opened on the client machine instead of proxied through the workspace. +- `external` (Boolean) Specifies whether `url` is opened on the client machine instead of proxied through the workspace. - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. -- `name` (String, Deprecated: `name` on apps is deprecated, use `display_name` instead) A display name to identify the app. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. +- `name` (String, **Deprecated**: `name` on apps is deprecated, use `display_name` instead) A display name to identify the app. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). -- `relative_path` (Boolean, Deprecated: `relative_path` on apps is deprecated, use `subdomain` instead.) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true. -- `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). -- `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false. -- `url` (String) An external url if "external=true" or a URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both. +- `relative_path` (Boolean, **Deprecated**: `relative_path` on apps is deprecated, use `subdomain` instead.) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to `true`. +- `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). +- `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with `subdomain` set to `true` will not be accessible. Defaults to `false`. +- `url` (String) An external url if `external=true` or a URL to be proxied to from inside the workspace. This should be of the form `http://localhost:PORT[/SUBPATH]`. Either `command` or `url` may be specified, but not both. ### Read-Only @@ -82,4 +82,4 @@ Required: - `interval` (Number) Duration in seconds to wait between healthcheck requests. - `threshold` (Number) Number of consecutive heathcheck failures before returning an unhealthy status. -- `url` (String) HTTP address used determine the application readiness. A successful health check is a HTTP response code less than 500 returned before healthcheck.interval seconds. +- `url` (String) HTTP address used determine the application readiness. A successful health check is a HTTP response code less than 500 returned before `healthcheck.interval` seconds. diff --git a/docs/resources/env.md b/docs/resources/env.md index 3531335c..3a5a7f3a 100644 --- a/docs/resources/env.md +++ b/docs/resources/env.md @@ -3,12 +3,12 @@ page_title: "coder_env Resource - terraform-provider-coder" subcategory: "" description: |- - Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource. + Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the coder_agent resource. --- # coder_env (Resource) -Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource. +Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the `coder_agent` resource. ## Example Usage @@ -39,7 +39,7 @@ resource "coder_env" "internal_api_url" { ### Required -- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. - `name` (String) The name of the environment variable. ### Optional diff --git a/docs/resources/metadata.md b/docs/resources/metadata.md index 9d6ff92f..f739db14 100644 --- a/docs/resources/metadata.md +++ b/docs/resources/metadata.md @@ -59,14 +59,14 @@ resource "coder_metadata" "pod_info" { ### Required -- `resource_id` (String) The "id" property of another resource that metadata should be attached to. +- `resource_id` (String) The `id` property of another resource that metadata should be attached to. ### Optional - `daily_cost` (Number) (Enterprise) The cost of this resource every 24 hours. Use the smallest denomination of your preferred currency. For example, if you work in USD, use cents. - `hide` (Boolean) Hide the resource from the UI. -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. -- `item` (Block List) Each "item" block defines a single metadata item consisting of a key/value pair. (see [below for nested schema](#nestedblock--item)) +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. +- `item` (Block List) Each `item` block defines a single metadata item consisting of a key/value pair. (see [below for nested schema](#nestedblock--item)) ### Read-Only @@ -81,7 +81,7 @@ Required: Optional: -- `sensitive` (Boolean) Set to "true" to for items such as API keys whose values should be hidden from view by default. Note that this does not prevent metadata from being retrieved using the API, so it is not suitable for secrets that should not be exposed to workspace users. +- `sensitive` (Boolean) Set to `true` to for items such as API keys whose values should be hidden from view by default. Note that this does not prevent metadata from being retrieved using the API, so it is not suitable for secrets that should not be exposed to workspace users. - `value` (String) The value of this metadata item. Read-Only: diff --git a/docs/resources/script.md b/docs/resources/script.md index d4d5dd9f..22ac1b50 100644 --- a/docs/resources/script.md +++ b/docs/resources/script.md @@ -72,14 +72,14 @@ resource "coder_script" "shutdown" { ### Required -- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. - `display_name` (String) The display name of the script to display logs in the dashboard. - `script` (String) The content of the script that will be run. ### Optional - `cron` (String) The cron schedule to run the script on. This is a cron expression. -- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. +- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `log_path` (String) The path of a file to write the logs to. If relative, it will be appended to tmp. - `run_on_start` (Boolean) This option defines whether or not the script should run when the agent starts. The script should exit when it is done to signal that the agent is ready. - `run_on_stop` (Boolean) This option defines whether or not the script should run when the agent stops. The script should exit when it is done to signal that the workspace can be stopped. diff --git a/provider/agent.go b/provider/agent.go index 0ff5ca21..352dd5d9 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -92,7 +92,7 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Required: true, - Description: `The architecture the agent will run on. Must be one of: "amd64", "armv7", "arm64".`, + Description: "The architecture the agent will run on. Must be one of: `\"amd64\"`, `\"armv7\"`, `\"arm64\"`.", ValidateFunc: validation.StringInSlice([]string{"amd64", "armv7", "arm64"}, false), }, "auth": { @@ -100,14 +100,14 @@ func agentResource() *schema.Resource { Default: "token", ForceNew: true, Optional: true, - Description: `The authentication type the agent will use. Must be one of: "token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity".`, + Description: "The authentication type the agent will use. Must be one of: `\"token\"`, `\"google-instance-identity\"`, `\"aws-instance-identity\"`, `\"azure-instance-identity\"`.", ValidateFunc: validation.StringInSlice([]string{"token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity"}, false), }, "dir": { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: "The starting directory when a user creates a shell session. Defaults to $HOME.", + Description: "The starting directory when a user creates a shell session. Defaults to `\"$HOME\"`.", }, "env": { ForceNew: true, @@ -119,12 +119,12 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Required: true, - Description: `The operating system the agent will run on. Must be one of: "linux", "darwin", or "windows".`, + Description: "The operating system the agent will run on. Must be one of: `\"linux\"`, `\"darwin\"`, or `\"windows\"`.", ValidateFunc: validation.StringInSlice([]string{"linux", "darwin", "windows"}, false), }, "startup_script": { ForceNew: true, - Description: `A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a "coder_script" resource with "run_on_start" set to true.`, + Description: "A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a `coder_script` resource with `run_on_start` set to `true`.", Type: schema.TypeString, Optional: true, }, @@ -141,7 +141,7 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: `A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a "coder_script" resource with "run_on_stop" set to true.`, + Description: "A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a `coder_script` resource with `run_on_stop` set to `true`.", }, "shutdown_script_timeout": { Type: schema.TypeInt, @@ -155,7 +155,7 @@ func agentResource() *schema.Resource { "token": { ForceNew: true, Sensitive: true, - Description: `Set the environment variable "CODER_AGENT_TOKEN" with this token to authenticate an agent.`, + Description: "Set the environment variable `CODER_AGENT_TOKEN` with this token to authenticate an agent.", Type: schema.TypeString, Computed: true, }, @@ -177,7 +177,7 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: "The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd.", + Description: "The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be `\"/etc/motd\"`.", }, "login_before_ready": { // Note: When this is removed, "startup_script_behavior" should @@ -186,8 +186,8 @@ func agentResource() *schema.Resource { Default: true, ForceNew: true, Optional: true, - Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in.", - Deprecated: "Configure startup_script_behavior instead. This attribute will be removed in a future version of the provider.", + Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the `startup_script` is done and has exited. When enabled, users may see an incomplete workspace when logging in.", + Deprecated: "Configure `startup_script_behavior` instead. This attribute will be removed in a future version of the provider.", ConflictsWith: []string{"startup_script_behavior"}, }, "startup_script_behavior": { @@ -200,13 +200,13 @@ func agentResource() *schema.Resource { Type: schema.TypeString, ForceNew: true, Optional: true, - Description: `This option sets the behavior of the "startup_script". When set to "blocking", the startup_script must exit before the workspace is ready. When set to "non-blocking", the startup_script may run in the background and the workspace will be ready immediately. Default is "non-blocking", although "blocking" is recommended. This option is an alias for defining a "coder_script" resource with "start_blocks_login" set to true (blocking).`, + Description: "This option sets the behavior of the `startup_script`. When set to `\"blocking\"`, the `startup_script` must exit before the workspace is ready. When set to `\"non-blocking\"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `\"non-blocking\"`, although `\"blocking\"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking).", ValidateFunc: validation.StringInSlice([]string{"blocking", "non-blocking"}, false), ConflictsWith: []string{"login_before_ready"}, }, "metadata": { Type: schema.TypeList, - Description: "Each \"metadata\" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases.", + Description: "Each `metadata` block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases.", ForceNew: true, Optional: true, Elem: &schema.Resource{ @@ -313,9 +313,9 @@ func agentResource() *schema.Resource { func agentInstanceResource() *schema.Resource { return &schema.Resource{ Description: "Use this resource to associate an instance ID with an agent for zero-trust " + - "authentication. This association is done automatically for \"google_compute_instance\", " + - "\"aws_instance\", \"azurerm_linux_virtual_machine\", and " + - "\"azurerm_windows_virtual_machine\" resources.", + "authentication. This association is done automatically for `\"google_compute_instance\"`, " + + "`\"aws_instance\"`, `\"azurerm_linux_virtual_machine\"`, and " + + "`\"azurerm_windows_virtual_machine\"` resources.", CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { resourceData.SetId(uuid.NewString()) return nil @@ -329,14 +329,14 @@ func agentInstanceResource() *schema.Resource { Schema: map[string]*schema.Schema{ "agent_id": { Type: schema.TypeString, - Description: `The "id" property of a "coder_agent" resource to associate with.`, + Description: "The `id` property of a `coder_agent` resource to associate with.", ForceNew: true, Required: true, }, "instance_id": { ForceNew: true, Required: true, - Description: `The instance identifier of a provisioned resource.`, + Description: "The instance identifier of a provisioned resource.", Type: schema.TypeString, }, }, diff --git a/provider/app.go b/provider/app.go index c2690311..91c08f0f 100644 --- a/provider/app.go +++ b/provider/app.go @@ -41,7 +41,7 @@ func appResource() *schema.Resource { Schema: map[string]*schema.Schema{ "agent_id": { Type: schema.TypeString, - Description: `The "id" property of a "coder_agent" resource to associate with.`, + Description: "The `id` property of a `coder_agent` resource to associate with.", ForceNew: true, Required: true, }, @@ -49,7 +49,7 @@ func appResource() *schema.Resource { Type: schema.TypeString, Description: "A command to run in a terminal opening this app. In the web, " + "this will open in a new tab. In the CLI, this will SSH and execute the command. " + - "Either \"command\" or \"url\" may be specified, but not both.", + "Either `command` or `url` may be specified, but not both.", ConflictsWith: []string{"url"}, Optional: true, ForceNew: true, @@ -58,7 +58,7 @@ func appResource() *schema.Resource { Type: schema.TypeString, Description: "A URL to an icon that will display in the dashboard. View built-in " + "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + - "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + "built-in icon with `\"${data.coder_workspace.me.access_url}/icon/\"`.", ForceNew: true, Optional: true, ValidateFunc: func(i interface{}, s string) ([]string, []error) { @@ -84,7 +84,7 @@ func appResource() *schema.Resource { } if !appSlugRegex.MatchString(valStr) { - return diag.Errorf("invalid coder_app slug, must be a valid hostname (%q, cannot contain two consecutive hyphens or start/end with a hyphen): %q", appSlugRegex.String(), valStr) + return diag.Errorf(`invalid "coder_app" slug, must be a valid hostname (%q, cannot contain two consecutive hyphens or start/end with a hyphen): %q`, appSlugRegex.String(), valStr) } return nil @@ -109,7 +109,7 @@ func appResource() *schema.Resource { Description: "Determines whether the app will be accessed via it's own " + "subdomain or whether it will be accessed via a path on Coder. If " + "wildcards have not been setup by the administrator then apps with " + - "\"subdomain\" set to true will not be accessible. Defaults to false.", + "`subdomain` set to `true` will not be accessible. Defaults to `false`.", ForceNew: true, Optional: true, }, @@ -117,19 +117,19 @@ func appResource() *schema.Resource { Type: schema.TypeBool, Deprecated: "`relative_path` on apps is deprecated, use `subdomain` instead.", Description: "Specifies whether the URL will be accessed via a relative " + - "path or wildcard. Use if wildcard routing is unavailable. Defaults to true.", + "path or wildcard. Use if wildcard routing is unavailable. Defaults to `true`.", ForceNew: true, Optional: true, ConflictsWith: []string{"subdomain"}, }, "share": { Type: schema.TypeString, - Description: `Determines the "level" which the application ` + - `is shared at. Valid levels are "owner" (default), ` + - `"authenticated" and "public". Level "owner" disables ` + + Description: "Determines the level which the application " + + "is shared at. Valid levels are `\"owner\"` (default), " + + "`\"authenticated\"` and `\"public\"`. Level `\"owner\"` disables " + "sharing on the app, so only the workspace owner can " + - `access it. Level "authenticated" shares the app with ` + - `all authenticated users. Level "public" shares it with ` + + "access it. Level `\"authenticated\"` shares the app with " + + "all authenticated users. Level `\"public\"` shares it with " + "any user, including unauthenticated users. Permitted " + "application sharing levels can be configured site-wide " + "via a flag on `coder server` (Enterprise only).", @@ -147,21 +147,21 @@ func appResource() *schema.Resource { return nil } - return diag.Errorf(`invalid app share %q, must be one of "owner", "authenticated", "public"`, valStr) + return diag.Errorf("invalid app share %q, must be one of \"owner\", \"authenticated\", \"public\"", valStr) }, }, "url": { Type: schema.TypeString, - Description: "An external url if \"external=true\" or a URL to be proxied to from inside the workspace. " + - "This should be of the form \"http://localhost:PORT[/SUBPATH]\". " + - "Either \"command\" or \"url\" may be specified, but not both.", + Description: "An external url if `external=true` or a URL to be proxied to from inside the workspace. " + + "This should be of the form `http://localhost:PORT[/SUBPATH]`. " + + "Either `command` or `url` may be specified, but not both.", ForceNew: true, Optional: true, ConflictsWith: []string{"command"}, }, "external": { Type: schema.TypeBool, - Description: "Specifies whether \"url\" is opened on the client machine " + + Description: "Specifies whether `url` is opened on the client machine " + "instead of proxied through the workspace.", Default: false, ForceNew: true, @@ -179,7 +179,7 @@ func appResource() *schema.Resource { Schema: map[string]*schema.Schema{ "url": { Type: schema.TypeString, - Description: "HTTP address used determine the application readiness. A successful health check is a HTTP response code less than 500 returned before healthcheck.interval seconds.", + Description: "HTTP address used determine the application readiness. A successful health check is a HTTP response code less than 500 returned before `healthcheck.interval` seconds.", ForceNew: true, Required: true, }, diff --git a/provider/env.go b/provider/env.go index 8f55ff8c..d45201ee 100644 --- a/provider/env.go +++ b/provider/env.go @@ -14,7 +14,7 @@ func envResource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, - Description: `Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the "coder_agent" resource.`, + Description: "Use this resource to set an environment variable in a workspace. Note that this resource cannot be used to overwrite existing environment variables set on the `coder_agent` resource.", CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { rd.SetId(uuid.NewString()) @@ -25,7 +25,7 @@ func envResource() *schema.Resource { Schema: map[string]*schema.Schema{ "agent_id": { Type: schema.TypeString, - Description: `The "id" property of a "coder_agent" resource to associate with.`, + Description: "The `id` property of a `coder_agent` resource to associate with.", ForceNew: true, Required: true, }, diff --git a/provider/gitauth.go b/provider/gitauth.go index 72c05bcd..e8230ade 100644 --- a/provider/gitauth.go +++ b/provider/gitauth.go @@ -16,7 +16,7 @@ func gitAuthDataSource() *schema.Resource { SchemaVersion: 1, DeprecationMessage: "Use the `coder_external_auth` data source instead.", - Description: "Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", + Description: "~> **Deprecated**\nUse the `coder_external_auth` data source instead.\n\nUse this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { rawID, ok := rd.GetOk("id") if !ok { diff --git a/provider/metadata.go b/provider/metadata.go index 00b488e4..abfe0a05 100644 --- a/provider/metadata.go +++ b/provider/metadata.go @@ -38,7 +38,7 @@ func metadataResource() *schema.Resource { Schema: map[string]*schema.Schema{ "resource_id": { Type: schema.TypeString, - Description: "The \"id\" property of another resource that metadata should be attached to.", + Description: "The `id` property of another resource that metadata should be attached to.", ForceNew: true, Required: true, }, @@ -51,8 +51,8 @@ func metadataResource() *schema.Resource { "icon": { Type: schema.TypeString, Description: "A URL to an icon that will display in the dashboard. View built-in " + - "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + - "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + "icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " + + "built-in icon with `\"${data.coder_workspace.me.access_url}/icon/\"`.", ForceNew: true, Optional: true, ValidateFunc: func(i interface{}, s string) ([]string, []error) { @@ -73,7 +73,7 @@ func metadataResource() *schema.Resource { }, "item": { Type: schema.TypeList, - Description: "Each \"item\" block defines a single metadata item consisting of a key/value pair.", + Description: "Each `item` block defines a single metadata item consisting of a key/value pair.", ForceNew: true, Optional: true, Elem: &schema.Resource{ @@ -92,7 +92,7 @@ func metadataResource() *schema.Resource { }, "sensitive": { Type: schema.TypeBool, - Description: "Set to \"true\" to for items such as API keys whose values should be " + + Description: "Set to `true` to for items such as API keys whose values should be " + "hidden from view by default. Note that this does not prevent metadata from " + "being retrieved using the API, so it is not suitable for secrets that should " + "not be exposed to workspace users.", diff --git a/provider/parameter.go b/provider/parameter.go index 281537f6..00dd5f34 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -204,7 +204,7 @@ func parameterDataSource() *schema.Resource { Default: "string", Optional: true, ValidateFunc: validation.StringInSlice([]string{"number", "string", "bool", "list(string)"}, false), - Description: `The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)".`, + Description: "The type of this parameter. Must be one of: `\"number\"`, `\"string\"`, `\"bool\"`, or `\"list(string)\"`.", }, "mutable": { Type: schema.TypeBool, @@ -221,7 +221,7 @@ func parameterDataSource() *schema.Resource { Type: schema.TypeString, Description: "A URL to an icon that will display in the dashboard. View built-in " + "icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " + - "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + "built-in icon with `\"${data.coder_workspace.me.access_url}/icon/\"`.", ForceNew: true, Optional: true, ValidateFunc: func(i interface{}, s string) ([]string, []error) { @@ -234,7 +234,7 @@ func parameterDataSource() *schema.Resource { }, "option": { Type: schema.TypeList, - Description: "Each \"option\" block defines a value for a user to select from.", + Description: "Each `option` block defines a value for a user to select from.", ForceNew: true, Optional: true, MaxItems: 64, @@ -261,8 +261,8 @@ func parameterDataSource() *schema.Resource { "icon": { Type: schema.TypeString, Description: "A URL to an icon that will display in the dashboard. View built-in " + - "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + - "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + "icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " + + "built-in icon with `\"${data.coder_workspace.me.access_url}/icon/\"`.", ForceNew: true, Optional: true, ValidateFunc: func(i interface{}, s string) ([]string, []error) { diff --git a/provider/script.go b/provider/script.go index 536a5732..df436ead 100644 --- a/provider/script.go +++ b/provider/script.go @@ -26,10 +26,10 @@ func scriptResource() *schema.Resource { cron, _ := rd.Get("cron").(string) if !runOnStart && !runOnStop && cron == "" { - return diag.Errorf("at least one of run_on_start, run_on_stop, or cron must be set") + return diag.Errorf(`at least one of "run_on_start", "run_on_stop", or "cron" must be set`) } if !runOnStart && startBlocksLogin { - return diag.Errorf("start_blocks_login can only be set if run_on_start is true") + return diag.Errorf(`"start_blocks_login" can only be set if "run_on_start" is "true"`) } return nil }, @@ -38,7 +38,7 @@ func scriptResource() *schema.Resource { Schema: map[string]*schema.Schema{ "agent_id": { Type: schema.TypeString, - Description: `The "id" property of a "coder_agent" resource to associate with.`, + Description: "The `id` property of a `coder_agent` resource to associate with.", ForceNew: true, Required: true, }, @@ -59,8 +59,8 @@ func scriptResource() *schema.Resource { ForceNew: true, Optional: true, Description: "A URL to an icon that will display in the dashboard. View built-in " + - "icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a " + - "built-in icon with `data.coder_workspace.me.access_url + \"/icon/\"`.", + "icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a " + + "built-in icon with `\"${data.coder_workspace.me.access_url}/icon/\"`.", }, "script": { ForceNew: true, diff --git a/provider/script_test.go b/provider/script_test.go index 937c6008..9b6bd570 100644 --- a/provider/script_test.go +++ b/provider/script_test.go @@ -69,7 +69,7 @@ func TestScriptNeverRuns(t *testing.T) { script = "Wow" } `, - ExpectError: regexp.MustCompile(`at least one of run_on_start, run_on_stop, or cron must be set`), + ExpectError: regexp.MustCompile(`at least one of "run_on_start", "run_on_stop", or "cron" must be set`), }}, }) } @@ -94,7 +94,7 @@ func TestScriptStartBlocksLoginRequiresRunOnStart(t *testing.T) { start_blocks_login = true } `, - ExpectError: regexp.MustCompile(`start_blocks_login can only be set if run_on_start is true`), + ExpectError: regexp.MustCompile(`"start_blocks_login" can only be set if "run_on_start" is "true"`), }}, }) resource.Test(t, resource.TestCase{ diff --git a/provider/workspace.go b/provider/workspace.go index d8bfd3a5..3f667e8f 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -115,12 +115,12 @@ func workspaceDataSource() *schema.Resource { "start_count": { Type: schema.TypeInt, Computed: true, - Description: `A computed count based on "transition" state. If "start", count will equal 1.`, + Description: "A computed count based on `transition` state. If `start`, count will equal 1.", }, "transition": { Type: schema.TypeString, Computed: true, - Description: `Either "start" or "stop". Use this to start/stop resources with "count".`, + Description: "Either `start` or `stop`. Use this to start/stop resources with `count`.", }, "owner": { Type: schema.TypeString, diff --git a/scripts/docsgen/main.go b/scripts/docsgen/main.go index 90244ccd..d83cf123 100644 --- a/scripts/docsgen/main.go +++ b/scripts/docsgen/main.go @@ -84,6 +84,6 @@ func writeDeprecationMessage(doc []byte, schemas map[string]*schema.Schema) []by log.Printf("warn: same property name `%s` but description does not match, most likely a different property", propertyName) return m } - return bytes.Replace(m, []byte("Deprecated"), []byte(fmt.Sprintf("Deprecated: %s", sch.Deprecated)), 1) + return bytes.Replace(m, []byte("Deprecated"), []byte(fmt.Sprintf("**Deprecated**: %s", sch.Deprecated)), 1) }) } From 3022367b60b7d7c535101798ce17270832552fd6 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 5 Jul 2024 11:40:20 +0300 Subject: [PATCH 088/173] ci: drop terraform versions < 1.5.x, add 1.9.x for tests (#258) --- .github/workflows/test.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f17d1c10..57faf626 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,15 +64,11 @@ jobs: fail-fast: false matrix: terraform: - - "1.0.*" - - "1.1.*" - - "1.2.*" - - "1.3.*" - - "1.4.*" - "1.5.*" - "1.6.*" - "1.7.*" - "1.8.*" + - "1.9.*" steps: - name: Set up Go uses: actions/setup-go@v5 @@ -112,7 +108,7 @@ jobs: - uses: hashicorp/setup-terraform@v3 with: - terraform_version: "1.3.*" + terraform_version: "latest" terraform_wrapper: false - name: Check out code into the Go module directory From 7ed088d0942fc4b24cf26c3e031a15618667f3c0 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 5 Jul 2024 11:40:47 +0300 Subject: [PATCH 089/173] chore!: remove deprecated items from `coder_workspace` data source (#255) --- docs/data-sources/workspace.md | 53 ++++++++++--- docs/data-sources/workspace_owner.md | 6 +- .../coder_workspace/data-source.tf | 46 ++++++++++- .../coder_workspace_owner/data-source.tf | 6 +- integration/integration_test.go | 38 +++------- integration/test-data-source/main.tf | 10 +-- integration/workspace-owner/main.tf | 10 +-- provider/workspace.go | 76 ------------------- provider/workspace_test.go | 29 +------ 9 files changed, 107 insertions(+), 167 deletions(-) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 8b824c37..26396ba1 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -13,11 +13,51 @@ Use this data source to get information for the active workspace build. ## Example Usage ```terraform -data "coder_workspace" "dev" { +provider "coder" {} + +provider "docker" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = "/workspace" } -resource "kubernetes_pod" "dev" { - count = data.coder_workspace.dev.transition == "start" ? 1 : 0 +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.main.name + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + # Use the docker gateway if the access URL is 127.0.0.1 + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } } ``` @@ -30,13 +70,6 @@ resource "kubernetes_pod" "dev" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `name` (String) Name of the workspace. -- `owner` (String, **Deprecated**: Use `coder_workspace_owner.name` instead.) Username of the workspace owner. -- `owner_email` (String, **Deprecated**: Use `coder_workspace_owner.email` instead.) Email address of the workspace owner. -- `owner_groups` (List of String, **Deprecated**: Use `coder_workspace_owner.groups` instead.) List of groups the workspace owner belongs to. -- `owner_id` (String, **Deprecated**: Use `coder_workspace_owner.id` instead.) UUID of the workspace owner. -- `owner_name` (String, **Deprecated**: Use `coder_workspace_owner.full_name` instead.) Name of the workspace owner. -- `owner_oidc_access_token` (String, **Deprecated**: Use `coder_workspace_owner.oidc_access_token` instead.) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String, **Deprecated**: Use `coder_workspace_owner.session_token` instead.) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on `transition` state. If `start`, count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index 0deff622..1c64ea50 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -15,14 +15,12 @@ Use this data source to fetch information about the workspace owner. ```terraform provider "coder" {} -data "coder_workspace" "me" {} - data "coder_workspace_owner" "me" {} resource "coder_agent" "dev" { arch = "amd64" os = "linux" - dir = local.repo_dir + dir = "/workspace" env = { OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, } @@ -36,7 +34,7 @@ resource "coder_env" "git_author_name" { } resource "coder_env" "git_author_email" { - agent_id = var.agent_id + agent_id = coder_agent.dev.id name = "GIT_AUTHOR_EMAIL" value = data.coder_workspace_owner.me.email count = data.coder_workspace_owner.me.email != "" ? 1 : 0 diff --git a/examples/data-sources/coder_workspace/data-source.tf b/examples/data-sources/coder_workspace/data-source.tf index 4898439b..8eb4a8f8 100644 --- a/examples/data-sources/coder_workspace/data-source.tf +++ b/examples/data-sources/coder_workspace/data-source.tf @@ -1,6 +1,46 @@ -data "coder_workspace" "dev" { +provider "coder" {} + +provider "docker" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = "/workspace" } -resource "kubernetes_pod" "dev" { - count = data.coder_workspace.dev.transition == "start" ? 1 : 0 +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.main.name + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + # Use the docker gateway if the access URL is 127.0.0.1 + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } } diff --git a/examples/data-sources/coder_workspace_owner/data-source.tf b/examples/data-sources/coder_workspace_owner/data-source.tf index fc27db6c..cad73e1e 100644 --- a/examples/data-sources/coder_workspace_owner/data-source.tf +++ b/examples/data-sources/coder_workspace_owner/data-source.tf @@ -1,13 +1,11 @@ provider "coder" {} -data "coder_workspace" "me" {} - data "coder_workspace_owner" "me" {} resource "coder_agent" "dev" { arch = "amd64" os = "linux" - dir = local.repo_dir + dir = "/workspace" env = { OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, } @@ -21,7 +19,7 @@ resource "coder_env" "git_author_name" { } resource "coder_env" "git_author_email" { - agent_id = var.agent_id + agent_id = coder_agent.dev.id name = "GIT_AUTHOR_EMAIL" value = data.coder_workspace_owner.me.email count = data.coder_workspace_owner.me.email != "" ? 1 : 0 diff --git a/integration/integration_test.go b/integration/integration_test.go index 75b35d20..8208d20a 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -71,25 +71,18 @@ func TestIntegration(t *testing.T) { name: "test-data-source", minVersion: "v0.0.0", expectedOutput: map[string]string{ - "provisioner.arch": runtime.GOARCH, - "provisioner.id": `[a-zA-Z0-9-]+`, - "provisioner.os": runtime.GOOS, - "workspace.access_port": `\d+`, - "workspace.access_url": `https?://\D+:\d+`, - "workspace.id": `[a-zA-z0-9-]+`, - "workspace.name": `test-data-source`, - "workspace.owner": `testing`, - "workspace.owner_email": `testing@coder\.com`, - "workspace.owner_groups": `\[\]`, - "workspace.owner_id": `[a-zA-Z0-9]+`, - "workspace.owner_name": `default`, - "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration - "workspace.owner_session_token": `[a-zA-Z0-9-]+`, - "workspace.start_count": `1`, - "workspace.template_id": `[a-zA-Z0-9-]+`, - "workspace.template_name": `test-data-source`, - "workspace.template_version": `.+`, - "workspace.transition": `start`, + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": `test-data-source`, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `test-data-source`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, }, }, { @@ -103,13 +96,6 @@ func TestIntegration(t *testing.T) { "workspace.access_url": `https?://\D+:\d+`, "workspace.id": `[a-zA-z0-9-]+`, "workspace.name": ``, - "workspace.owner": `testing`, - "workspace.owner_email": `testing@coder\.com`, - "workspace.owner_groups": `\[\]`, - "workspace.owner_id": `[a-zA-Z0-9]+`, - "workspace.owner_name": `default`, - "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration - "workspace.owner_session_token": `[a-zA-Z0-9-]+`, "workspace.start_count": `1`, "workspace.template_id": `[a-zA-Z0-9-]+`, "workspace.template_name": `workspace-owner`, diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 838125a0..6d4b85cd 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -9,9 +9,8 @@ terraform { } } -// TODO: test coder_external_auth and coder_git_auth +// TODO: test coder_external_auth // data coder_external_auth "me" {} -// data coder_git_auth "me" {} data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} @@ -26,13 +25,6 @@ locals { "workspace.access_url" : data.coder_workspace.me.access_url, "workspace.id" : data.coder_workspace.me.id, "workspace.name" : data.coder_workspace.me.name, - "workspace.owner" : data.coder_workspace.me.owner, - "workspace.owner_email" : data.coder_workspace.me.owner_email, - "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), - "workspace.owner_id" : data.coder_workspace.me.owner_id, - "workspace.owner_name" : data.coder_workspace.me.owner_name, - "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, - "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, "workspace.start_count" : tostring(data.coder_workspace.me.start_count), "workspace.template_id" : data.coder_workspace.me.template_id, "workspace.template_name" : data.coder_workspace.me.template_name, diff --git a/integration/workspace-owner/main.tf b/integration/workspace-owner/main.tf index 580592cb..2be11d8e 100644 --- a/integration/workspace-owner/main.tf +++ b/integration/workspace-owner/main.tf @@ -9,9 +9,8 @@ terraform { } } -// TODO: test coder_external_auth and coder_git_auth +// TODO: test coder_external_auth // data coder_external_auth "me" {} -// data coder_git_auth "me" {} data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} @@ -26,13 +25,6 @@ locals { "workspace.access_url" : data.coder_workspace.me.access_url, "workspace.id" : data.coder_workspace.me.id, "workspace.name" : data.coder_workspace.me.name, - "workspace.owner" : data.coder_workspace.me.owner, - "workspace.owner_email" : data.coder_workspace.me.owner_email, - "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), - "workspace.owner_id" : data.coder_workspace.me.owner_id, - "workspace.owner_name" : data.coder_workspace.me.owner_name, - "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, - "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, "workspace.start_count" : tostring(data.coder_workspace.me.start_count), "workspace.template_id" : data.coder_workspace.me.template_id, "workspace.template_name" : data.coder_workspace.me.template_name, diff --git a/provider/workspace.go b/provider/workspace.go index 3f667e8f..575fd60f 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -2,7 +2,6 @@ package provider import ( "context" - "encoding/json" "reflect" "strconv" @@ -28,37 +27,9 @@ func workspaceDataSource() *schema.Resource { } _ = rd.Set("start_count", count) - owner := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER", "default") - _ = rd.Set("owner", owner) - - ownerEmail := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_EMAIL", "default@example.com") - _ = rd.Set("owner_email", ownerEmail) - - ownerGroupsText := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_GROUPS") - var ownerGroups []string - if ownerGroupsText != "" { - err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) - if err != nil { - return diag.Errorf("couldn't parse owner groups %q", ownerGroupsText) - } - } - _ = rd.Set("owner_groups", ownerGroups) - - ownerName := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_NAME", "default") - _ = rd.Set("owner_name", ownerName) - - ownerID := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_ID", uuid.Nil.String()) - _ = rd.Set("owner_id", ownerID) - - ownerOIDCAccessToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN") - _ = rd.Set("owner_oidc_access_token", ownerOIDCAccessToken) - name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) - sessionToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_SESSION_TOKEN") - _ = rd.Set("owner_session_token", sessionToken) - id := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_ID", uuid.NewString()) rd.SetId(id) @@ -122,47 +93,6 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Either `start` or `stop`. Use this to start/stop resources with `count`.", }, - "owner": { - Type: schema.TypeString, - Computed: true, - Description: "Username of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.name` instead.", - }, - "owner_email": { - Type: schema.TypeString, - Computed: true, - Description: "Email address of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.email` instead.", - }, - "owner_id": { - Type: schema.TypeString, - Computed: true, - Description: "UUID of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.id` instead.", - }, - "owner_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.full_name` instead.", - }, - "owner_oidc_access_token": { - Type: schema.TypeString, - Computed: true, - Description: "A valid OpenID Connect access token of the workspace owner. " + - "This is only available if the workspace owner authenticated with OpenID Connect. " + - "If a valid token cannot be obtained, this value will be an empty string.", - Deprecated: "Use `coder_workspace_owner.oidc_access_token` instead.", - }, - "owner_groups": { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Computed: true, - Description: "List of groups the workspace owner belongs to.", - Deprecated: "Use `coder_workspace_owner.groups` instead.", - }, "id": { Type: schema.TypeString, Computed: true, @@ -173,12 +103,6 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Name of the workspace.", }, - "owner_session_token": { - Type: schema.TypeString, - Computed: true, - Description: "Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started.", - Deprecated: "Use `coder_workspace_owner.session_token` instead.", - }, "template_id": { Type: schema.TypeString, Computed: true, diff --git a/provider/workspace_test.go b/provider/workspace_test.go index e53f30d4..12d5210b 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -14,13 +14,6 @@ import ( ) func TestWorkspace(t *testing.T) { - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") - t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") - t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) - t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -49,16 +42,9 @@ func TestWorkspace(t *testing.T) { t.Log(value) assert.Equal(t, "https://example.com:8080", attribs["access_url"]) assert.Equal(t, "8080", attribs["access_port"]) - assert.Equal(t, "owner123", attribs["owner"]) - assert.Equal(t, "11111111-1111-1111-1111-111111111111", attribs["owner_id"]) - assert.Equal(t, "Mr Owner", attribs["owner_name"]) - assert.Equal(t, "owner123@example.com", attribs["owner_email"]) - assert.Equal(t, "group1", attribs["owner_groups.0"]) - assert.Equal(t, "group2", attribs["owner_groups.1"]) assert.Equal(t, "templateID", attribs["template_id"]) assert.Equal(t, "template123", attribs["template_name"]) assert.Equal(t, "v1.2.3", attribs["template_version"]) - assert.Equal(t, "supersecret", attribs["owner_oidc_access_token"]) return nil }, }}, @@ -66,9 +52,6 @@ func TestWorkspace(t *testing.T) { } func TestWorkspace_UndefinedOwner(t *testing.T) { - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -95,8 +78,9 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { value := attribs["transition"] require.NotNil(t, value) t.Log(value) - assert.Equal(t, "owner123", attribs["owner"]) - assert.Equal(t, "default@example.com", attribs["owner_email"]) + assert.Equal(t, "templateID", attribs["template_id"]) + assert.Equal(t, "template123", attribs["template_name"]) + assert.Equal(t, "v1.2.3", attribs["template_version"]) // Skip other asserts return nil }, @@ -107,13 +91,6 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { func TestWorkspace_MissingTemplateName(t *testing.T) { t.Setenv("CODER_WORKSPACE_BUILD_ID", "1") // Let's pretend this is a workspace build - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") - t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") - t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) - t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") // CODER_WORKSPACE_TEMPLATE_NAME is missing t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") From 5ca08cbcbeef38fa215823ab90d4c50eb5159ed7 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 5 Jul 2024 11:41:01 +0300 Subject: [PATCH 090/173] chore!: remove deprecated `coder_git_auth` data source (#254) --- docs/data-sources/git_auth.md | 52 ------------------ .../coder_git_auth/data-source.tf | 20 ------- provider/gitauth.go | 53 ------------------- provider/gitauth_test.go | 44 --------------- provider/provider.go | 1 - provider/provider_test.go | 3 -- 6 files changed, 173 deletions(-) delete mode 100644 docs/data-sources/git_auth.md delete mode 100644 examples/data-sources/coder_git_auth/data-source.tf delete mode 100644 provider/gitauth.go delete mode 100644 provider/gitauth_test.go diff --git a/docs/data-sources/git_auth.md b/docs/data-sources/git_auth.md deleted file mode 100644 index e665aeb1..00000000 --- a/docs/data-sources/git_auth.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "coder_git_auth Data Source - terraform-provider-coder" -subcategory: "" -description: |- - ~> Deprecated - Use the coder_external_auth data source instead. - Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated git clone in startup scripts. ---- - -# coder_git_auth (Data Source) - -~> **Deprecated** -Use the `coder_external_auth` data source instead. - -Use this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts. - -## Example Usage - -```terraform -provider "coder" {} - -data "coder_git_auth" "github" { - # Matches the ID of the git auth provider in Coder. - id = "github" -} - -resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "~/coder" - env = { - GITHUB_TOKEN : data.coder_git_auth.github.access_token - } - startup_script = < -## Schema - -### Required - -- `id` (String) The identifier of a configured git auth provider set up in your Coder deployment. - -### Read-Only - -- `access_token` (String) The access token returned by the git authentication provider. This can be used to pre-authenticate command-line tools. diff --git a/examples/data-sources/coder_git_auth/data-source.tf b/examples/data-sources/coder_git_auth/data-source.tf deleted file mode 100644 index 488554f2..00000000 --- a/examples/data-sources/coder_git_auth/data-source.tf +++ /dev/null @@ -1,20 +0,0 @@ -provider "coder" {} - -data "coder_git_auth" "github" { - # Matches the ID of the git auth provider in Coder. - id = "github" -} - -resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "~/coder" - env = { - GITHUB_TOKEN : data.coder_git_auth.github.access_token - } - startup_script = < **Deprecated**\nUse the `coder_external_auth` data source instead.\n\nUse this data source to require users to authenticate with a Git provider prior to workspace creation. This can be used to perform an authenticated `git clone` in startup scripts.", - ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { - rawID, ok := rd.GetOk("id") - if !ok { - return diag.Errorf("id is required") - } - id, ok := rawID.(string) - if !ok { - return diag.Errorf("unexpected type %q for id", rawID) - } - rd.SetId(id) - - accessToken := helpers.OptionalEnv(GitAuthAccessTokenEnvironmentVariable(id)) - rd.Set("access_token", accessToken) - - return nil - }, - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Required: true, - Description: "The identifier of a configured git auth provider set up in your Coder deployment.", - }, - "access_token": { - Type: schema.TypeString, - Computed: true, - Description: "The access token returned by the git authentication provider. This can be used to pre-authenticate command-line tools.", - }, - }, - } -} - -func GitAuthAccessTokenEnvironmentVariable(id string) string { - return fmt.Sprintf("CODER_GIT_AUTH_ACCESS_TOKEN_%s", id) -} diff --git a/provider/gitauth_test.go b/provider/gitauth_test.go deleted file mode 100644 index 481d79f5..00000000 --- a/provider/gitauth_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package provider_test - -import ( - "testing" - - "github.com/coder/terraform-provider-coder/provider" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/stretchr/testify/require" -) - -func TestGitAuth(t *testing.T) { - t.Parallel() - - resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, - Steps: []resource.TestStep{{ - Config: ` - provider "coder" { - } - data "coder_git_auth" "github" { - id = "github" - } - `, - Check: func(state *terraform.State) error { - require.Len(t, state.Modules, 1) - require.Len(t, state.Modules[0].Resources, 1) - resource := state.Modules[0].Resources["data.coder_git_auth.github"] - require.NotNil(t, resource) - - attribs := resource.Primary.Attributes - require.Equal(t, "github", attribs["id"]) - - return nil - }, - }}, - }) -} diff --git a/provider/provider.go b/provider/provider.go index c1991a26..4d513139 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -72,7 +72,6 @@ func New() *schema.Provider { "coder_workspace_tags": workspaceTagDataSource(), "coder_provisioner": provisionerDataSource(), "coder_parameter": parameterDataSource(), - "coder_git_auth": gitAuthDataSource(), "coder_external_auth": externalAuthDataSource(), "coder_workspace_owner": workspaceOwnerDataSource(), }, diff --git a/provider/provider_test.go b/provider/provider_test.go index 7069db09..742eb30b 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -37,9 +37,6 @@ func TestProviderEmpty(t *testing.T) { data "coder_external_auth" "git" { id = "git" } - data "coder_git_auth" "git" { - id = "git" - } data "coder_parameter" "param" { name = "hey" }`, From f46148f247afcb5fa8b1127cf27ebab77d9120f0 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 5 Jul 2024 11:41:12 +0300 Subject: [PATCH 091/173] chore!: remove deprecated feature_use_managed_variables (#256) --- docs/index.md | 1 - provider/provider.go | 7 ------- 2 files changed, 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index a4dfd70e..859964d4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,5 +62,4 @@ resource "google_compute_instance" "dev" { ### Optional -- `feature_use_managed_variables` (Boolean, **Deprecated**: Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.) Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables. - `url` (String) The URL to access Coder. \ No newline at end of file diff --git a/provider/provider.go b/provider/provider.go index 4d513139..1a37b706 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -35,13 +35,6 @@ func New() *schema.Provider { return nil, nil }, }, - "feature_use_managed_variables": { - Type: schema.TypeBool, - Description: "Feature: use managed Terraform variables. The feature flag is not used anymore as Terraform variables are now exclusively utilized for template-wide variables.", - Default: true, - Optional: true, - Deprecated: "Terraform variables are now exclusively utilized for template-wide variables after the removal of support for legacy parameters.", - }, }, ConfigureContextFunc: func(c context.Context, resourceData *schema.ResourceData) (interface{}, diag.Diagnostics) { rawURL, ok := resourceData.Get("url").(string) From dea044287505e28e99bac4b232c9a9e07f7eb8e3 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 5 Jul 2024 11:44:06 +0300 Subject: [PATCH 092/173] chore!: remove deprecated fields from `coder_app` and `coder_agent` resources (#257) --- docs/resources/agent.md | 3 --- docs/resources/app.md | 2 -- provider/agent.go | 47 ++++++----------------------------------- provider/agent_test.go | 32 ---------------------------- provider/app.go | 17 --------------- 5 files changed, 6 insertions(+), 95 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index e444d2d7..8c786d6e 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -76,15 +76,12 @@ resource "kubernetes_pod" "dev" { - `dir` (String) The starting directory when a user creates a shell session. Defaults to `"$HOME"`. - `display_apps` (Block Set, Max: 1) The list of built-in apps to display in the agent bar. (see [below for nested schema](#nestedblock--display_apps)) - `env` (Map of String) A mapping of environment variables to set inside the workspace. -- `login_before_ready` (Boolean, **Deprecated**: Configure `startup_script_behavior` instead. This attribute will be removed in a future version of the provider.) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the `startup_script` is done and has exited. When enabled, users may see an incomplete workspace when logging in. - `metadata` (Block List) Each `metadata` block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be `"/etc/motd"`. - `order` (Number) The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order). - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a `coder_script` resource with `run_on_stop` set to `true`. -- `shutdown_script_timeout` (Number, **Deprecated**: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a `coder_script` resource with `run_on_start` set to `true`. - `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to `"blocking"`, the `startup_script` must exit before the workspace is ready. When set to `"non-blocking"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `"non-blocking"`, although `"blocking"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking). -- `startup_script_timeout` (Number, **Deprecated**: This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.) Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time. - `troubleshooting_url` (String) A URL to a document with instructions for troubleshooting problems with the agent. ### Read-Only diff --git a/docs/resources/app.md b/docs/resources/app.md index f61ed799..1cb5d08b 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -64,9 +64,7 @@ resource "coder_app" "vim" { - `external` (Boolean) Specifies whether `url` is opened on the client machine instead of proxied through the workspace. - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. -- `name` (String, **Deprecated**: `name` on apps is deprecated, use `display_name` instead) A display name to identify the app. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). -- `relative_path` (Boolean, **Deprecated**: `relative_path` on apps is deprecated, use `subdomain` instead.) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to `true`. - `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with `subdomain` set to `true` will not be accessible. Defaults to `false`. - `url` (String) An external url if `external=true` or a URL to be proxied to from inside the workspace. This should be of the form `http://localhost:PORT[/SUBPATH]`. Either `command` or `url` may be specified, but not both. diff --git a/provider/agent.go b/provider/agent.go index 352dd5d9..d0ce4070 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -128,30 +128,12 @@ func agentResource() *schema.Resource { Type: schema.TypeString, Optional: true, }, - "startup_script_timeout": { - Type: schema.TypeInt, - Default: 300, - ForceNew: true, - Optional: true, - Description: "Time in seconds until the agent lifecycle status is marked as timed out during start, this happens when the startup script has not completed (exited) in the given time.", - Deprecated: "This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.", - ValidateFunc: validation.IntAtLeast(1), - }, "shutdown_script": { Type: schema.TypeString, ForceNew: true, Optional: true, Description: "A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a `coder_script` resource with `run_on_stop` set to `true`.", }, - "shutdown_script_timeout": { - Type: schema.TypeInt, - Default: 300, - ForceNew: true, - Optional: true, - Description: "Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time.", - Deprecated: "This feature is deprecated and has no effect. This attribute will be removed in a future version of the provider.", - ValidateFunc: validation.IntAtLeast(1), - }, "token": { ForceNew: true, Sensitive: true, @@ -179,30 +161,13 @@ func agentResource() *schema.Resource { Optional: true, Description: "The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be `\"/etc/motd\"`.", }, - "login_before_ready": { - // Note: When this is removed, "startup_script_behavior" should - // be set to "non-blocking" by default (instead of empty string). - Type: schema.TypeBool, - Default: true, - ForceNew: true, - Optional: true, - Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the `startup_script` is done and has exited. When enabled, users may see an incomplete workspace when logging in.", - Deprecated: "Configure `startup_script_behavior` instead. This attribute will be removed in a future version of the provider.", - ConflictsWith: []string{"startup_script_behavior"}, - }, "startup_script_behavior": { - // Note: Our default value is "non-blocking" but we do not set - // it here because we want to be able to differentiate between - // the user setting this or "login_before_ready". For all - // intents and purposes, until deprecation, setting - // "login_before_ready = false" is equivalent to setting - // "startup_script_behavior = blocking". - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Description: "This option sets the behavior of the `startup_script`. When set to `\"blocking\"`, the `startup_script` must exit before the workspace is ready. When set to `\"non-blocking\"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `\"non-blocking\"`, although `\"blocking\"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking).", - ValidateFunc: validation.StringInSlice([]string{"blocking", "non-blocking"}, false), - ConflictsWith: []string{"login_before_ready"}, + Type: schema.TypeString, + Default: "non-blocking", + ForceNew: true, + Optional: true, + Description: "This option sets the behavior of the `startup_script`. When set to `\"blocking\"`, the `startup_script` must exit before the workspace is ready. When set to `\"non-blocking\"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `\"non-blocking\"`, although `\"blocking\"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking).", + ValidateFunc: validation.StringInSlice([]string{"blocking", "non-blocking"}, false), }, "metadata": { Type: schema.TypeList, diff --git a/provider/agent_test.go b/provider/agent_test.go index 491e59f9..0df2cf2d 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -34,11 +34,9 @@ func TestAgent(t *testing.T) { hi = "test" } startup_script = "echo test" - startup_script_timeout = 120 troubleshooting_url = "https://example.com/troubleshoot" motd_file = "/etc/motd" shutdown_script = "echo bye bye" - shutdown_script_timeout = 120 order = 4 } `, @@ -55,12 +53,10 @@ func TestAgent(t *testing.T) { "dir", "env.hi", "startup_script", - "startup_script_timeout", "connection_timeout", "troubleshooting_url", "motd_file", "shutdown_script", - "shutdown_script_timeout", "order", } { value := resource.Primary.Attributes[key] @@ -109,34 +105,6 @@ func TestAgent_StartupScriptBehavior(t *testing.T) { require.Equal(t, "non-blocking", state.Primary.Attributes["startup_script_behavior"]) }, }, - { - Name: "login_before_ready (deprecated)", - Config: ` - resource "coder_agent" "new" { - os = "linux" - arch = "amd64" - login_before_ready = false - } - `, - Check: func(state *terraform.ResourceState) { - require.Equal(t, "false", state.Primary.Attributes["login_before_ready"]) - // startup_script_behavior must be empty, this indicates that - // login_before_ready should be used instead. - require.Equal(t, "", state.Primary.Attributes["startup_script_behavior"]) - }, - }, - { - Name: "no login_before_ready with startup_script_behavior", - Config: ` - resource "coder_agent" "new" { - os = "linux" - arch = "amd64" - login_before_ready = false - startup_script_behavior = "blocking" - } - `, - ExpectError: regexp.MustCompile("conflicts with"), - }, } { tc := tc t.Run(tc.Name, func(t *testing.T) { diff --git a/provider/app.go b/provider/app.go index 91c08f0f..754b0e2a 100644 --- a/provider/app.go +++ b/provider/app.go @@ -96,14 +96,6 @@ func appResource() *schema.Resource { ForceNew: true, Optional: true, }, - "name": { - Type: schema.TypeString, - Description: "A display name to identify the app.", - Deprecated: "`name` on apps is deprecated, use `display_name` instead", - ForceNew: true, - Optional: true, - ConflictsWith: []string{"display_name"}, - }, "subdomain": { Type: schema.TypeBool, Description: "Determines whether the app will be accessed via it's own " + @@ -113,15 +105,6 @@ func appResource() *schema.Resource { ForceNew: true, Optional: true, }, - "relative_path": { - Type: schema.TypeBool, - Deprecated: "`relative_path` on apps is deprecated, use `subdomain` instead.", - Description: "Specifies whether the URL will be accessed via a relative " + - "path or wildcard. Use if wildcard routing is unavailable. Defaults to `true`.", - ForceNew: true, - Optional: true, - ConflictsWith: []string{"subdomain"}, - }, "share": { Type: schema.TypeString, Description: "Determines the level which the application " + From f478379740aab9e2b3887cd04cbc740c97e5cfaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 13:08:06 +0300 Subject: [PATCH 093/173] build(deps): Bump goreleaser/goreleaser-action from 5.1.0 to 6.0.0 (#238) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Muhammad Atif Ali --- .github/workflows/release.yml | 4 ++-- .goreleaser.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ad8d96c9..6bf1284c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,10 +38,10 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5.1.0 + uses: goreleaser/goreleaser-action@v6.0.0 with: version: latest - args: release --rm-dist + args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} # GitHub sets this automatically diff --git a/.goreleaser.yml b/.goreleaser.yml index 0e43eeec..3866324a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -57,4 +57,4 @@ release: # If you want to manually examine the release before its live, uncomment this line: # draft: true changelog: - skip: true \ No newline at end of file + disable: true From 1d525fa819e14edf745e6acc5e110a8d14f470e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:34:54 +0100 Subject: [PATCH 094/173] build(deps): Bump github.com/docker/docker (#263) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.1.4+incompatible to 26.1.5+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v26.1.4...v26.1.5) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7e8aebe9..d83e1250 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 toolchain go1.22.3 require ( - github.com/docker/docker v26.1.4+incompatible + github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 diff --git a/go.sum b/go.sum index 79ed9f85..866fe7b5 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= -github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.1.5+incompatible h1:NEAxTwEjxV6VbBMBoGG3zPqbiJosIApZjxlbrG9q3/g= +github.com/docker/docker v26.1.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= From c174530d0753e691a2685a3b4817e505f03b8eff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:51:49 +0300 Subject: [PATCH 095/173] build(deps): Bump contributor-assistant/github-action (#269) Bumps [contributor-assistant/github-action](https://github.com/contributor-assistant/github-action) from 2.4.0 to 2.5.1. - [Release notes](https://github.com/contributor-assistant/github-action/releases) - [Commits](https://github.com/contributor-assistant/github-action/compare/v2.4.0...v2.5.1) --- updated-dependencies: - dependency-name: contributor-assistant/github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 412cac6b..494dddc8 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.4.0 + uses: contributor-assistant/github-action@v2.5.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From abd6cf02b58b40e21d61d699cb88a54d24858269 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:57:06 +0300 Subject: [PATCH 096/173] build(deps): Bump golang.org/x/mod from 0.18.0 to 0.20.0 (#265) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.18.0 to 0.20.0. - [Commits](https://github.com/golang/mod/compare/v0.18.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d83e1250..e4906a0e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.9.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.18.0 + golang.org/x/mod v0.20.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index 866fe7b5..231ca103 100644 --- a/go.sum +++ b/go.sum @@ -261,8 +261,8 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXy 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From 56aacf0190db16a4773f3dc7d0566253d8bb77e2 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 28 Aug 2024 21:01:44 +0300 Subject: [PATCH 097/173] docs: add description to provider index page (#271) * docs: add description to provider index page * fix typo --- docs/index.md | 4 +++- templates/index.md.tmpl | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 859964d4..7ce115a7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,11 +3,13 @@ page_title: "Coder Provider" subcategory: "Infrastructure" description: |- - + Terraform provider for managing Coder templates, which are the underlying infrastructure for Coder workspaces. --- # Coder Provider +Terraform provider for managing Coder [templates](https://coder.com/docs/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/workspaces). + ## Example ```terraform diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index 5ca983fd..de4ec73e 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -3,11 +3,13 @@ page_title: "Coder Provider" subcategory: "Infrastructure" description: |- - + Terraform provider for managing Coder templates, which are the underlying infrastructure for Coder workspaces. --- # Coder Provider +Terraform provider for managing Coder [templates](https://coder.com/docs/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/workspaces). + ## Example {{tffile "examples/provider/provider.tf"}} From e841c7074c8b612a94bd1eba42ebe23756b4010d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 21:15:53 +0100 Subject: [PATCH 098/173] build(deps): Bump google.golang.org/grpc from 1.64.0 to 1.64.1 (#262) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.64.0 to 1.64.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.64.0...v1.64.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index e4906a0e..17d00108 100644 --- a/go.mod +++ b/go.mod @@ -79,14 +79,14 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/grpc v1.64.1 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/go.sum b/go.sum index 231ca103..95a4084f 100644 --- a/go.sum +++ b/go.sum @@ -254,8 +254,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -277,8 +277,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -307,8 +307,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -317,8 +317,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -338,8 +338,8 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= From 286841d83d118034d20035dcf5ad9def95a56834 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:14:09 +1000 Subject: [PATCH 099/173] docs: clarify `coder_metadata` usage (#267) --- docs/resources/metadata.md | 9 ++++++--- provider/metadata.go | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/resources/metadata.md b/docs/resources/metadata.md index f739db14..d8329ea9 100644 --- a/docs/resources/metadata.md +++ b/docs/resources/metadata.md @@ -3,12 +3,15 @@ page_title: "coder_metadata Resource - terraform-provider-coder" subcategory: "" description: |- - Use this resource to attach metadata to a resource. They will be displayed in the Coder dashboard. + Use this resource to attach metadata to a resource. They will be displayed in the Coder dashboard alongside the resource. The resource containing the agent, and it's metadata, will be shown by default. + Alternatively, to attach metadata to the agent, use a metadata block within a coder_agent resource. --- # coder_metadata (Resource) -Use this resource to attach metadata to a resource. They will be displayed in the Coder dashboard. +Use this resource to attach metadata to a resource. They will be displayed in the Coder dashboard alongside the resource. The resource containing the agent, and it's metadata, will be shown by default. + +Alternatively, to attach metadata to the agent, use a `metadata` block within a `coder_agent` resource. ## Example Usage @@ -82,7 +85,7 @@ Required: Optional: - `sensitive` (Boolean) Set to `true` to for items such as API keys whose values should be hidden from view by default. Note that this does not prevent metadata from being retrieved using the API, so it is not suitable for secrets that should not be exposed to workspace users. -- `value` (String) The value of this metadata item. +- `value` (String) The value of this metadata item. Supports basic Markdown, including hyperlinks. Read-Only: diff --git a/provider/metadata.go b/provider/metadata.go index abfe0a05..48a3e89d 100644 --- a/provider/metadata.go +++ b/provider/metadata.go @@ -14,7 +14,9 @@ func metadataResource() *schema.Resource { SchemaVersion: 1, Description: "Use this resource to attach metadata to a resource. They will be " + - "displayed in the Coder dashboard.", + "displayed in the Coder dashboard alongside the resource. " + + "The resource containing the agent, and it's metadata, will be shown by default. " + "\n\n" + + "Alternatively, to attach metadata to the agent, use a `metadata` block within a `coder_agent` resource.", CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { resourceData.SetId(uuid.NewString()) @@ -86,7 +88,7 @@ func metadataResource() *schema.Resource { }, "value": { Type: schema.TypeString, - Description: "The value of this metadata item.", + Description: "The value of this metadata item. Supports basic Markdown, including hyperlinks.", ForceNew: true, Optional: true, }, From 5f660a0f7182975133fa768fcea67402e34b955c Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:25:18 +1000 Subject: [PATCH 100/173] fix: optional everyone group in integration test (#278) --- integration/integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/integration_test.go b/integration/integration_test.go index 8208d20a..b7132d18 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -103,7 +103,7 @@ func TestIntegration(t *testing.T) { "workspace.transition": `start`, "workspace_owner.email": `testing@coder\.com`, "workspace_owner.full_name": `default`, - "workspace_owner.groups": `\[\]`, + "workspace_owner.groups": `\[(\"Everyone\")?\]`, "workspace_owner.id": `[a-zA-Z0-9-]+`, "workspace_owner.name": `testing`, "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration From f69a14d433860536d9089aea5ebdc37ff807cb5d Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:28:31 +1000 Subject: [PATCH 101/173] fix: validate agent & resource metadata keys during plan (#277) --- provider/agent.go | 38 ++++++++++++++++++++++++++------------ provider/agent_test.go | 7 ++++--- provider/metadata.go | 27 +++++++++++++++++++++++++++ provider/metadata_test.go | 3 ++- provider/provider.go | 6 ------ 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/provider/agent.go b/provider/agent.go index d0ce4070..01fb5801 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -43,18 +43,6 @@ func agentResource() *schema.Resource { } } - rawPlan := resourceData.GetRawPlan() - items := rawPlan.GetAttr("metadata").AsValueSlice() - itemKeys := map[string]struct{}{} - for _, item := range items { - key := valueAsString(item.GetAttr("key")) - _, exists := itemKeys[key] - if exists { - return diag.FromErr(xerrors.Errorf("duplicate agent metadata key %q", key)) - } - itemKeys[key] = struct{}{} - } - return updateInitScript(resourceData, i) }, ReadWithoutTimeout: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { @@ -272,6 +260,32 @@ func agentResource() *schema.Resource { Optional: true, }, }, + CustomizeDiff: func(ctx context.Context, rd *schema.ResourceDiff, i any) error { + if !rd.HasChange("metadata") { + return nil + } + + keys := map[string]bool{} + metadata, ok := rd.Get("metadata").([]any) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata, expected []any", rd.Get("metadata")) + } + for _, t := range metadata { + obj, ok := t.(map[string]any) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata, expected map[string]any", t) + } + key, ok := obj["key"].(string) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata key, expected string", obj["key"]) + } + if keys[key] { + return xerrors.Errorf("duplicate agent metadata key %q", key) + } + keys[key] = true + } + return nil + }, } } diff --git a/provider/agent_test.go b/provider/agent_test.go index 0df2cf2d..91c708ca 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -254,6 +254,7 @@ func TestAgent_MetadataDuplicateKeys(t *testing.T) { } `, ExpectError: regexp.MustCompile("duplicate agent metadata key"), + PlanOnly: true, }}, }) } @@ -281,7 +282,7 @@ func TestAgent_DisplayApps(t *testing.T) { web_terminal = false port_forwarding_helper = false ssh_helper = false - } + } } `, Check: func(state *terraform.State) error { @@ -331,7 +332,7 @@ func TestAgent_DisplayApps(t *testing.T) { display_apps { vscode_insiders = true web_terminal = true - } + } } `, Check: func(state *terraform.State) error { @@ -426,7 +427,7 @@ func TestAgent_DisplayApps(t *testing.T) { web_terminal = false port_forwarding_helper = false ssh_helper = false - } + } } `, ExpectError: regexp.MustCompile(`An argument named "fake_app" is not expected here.`), diff --git a/provider/metadata.go b/provider/metadata.go index 48a3e89d..535c700c 100644 --- a/provider/metadata.go +++ b/provider/metadata.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "golang.org/x/xerrors" ) func metadataResource() *schema.Resource { @@ -111,5 +112,31 @@ func metadataResource() *schema.Resource { }, }, }, + CustomizeDiff: func(ctx context.Context, rd *schema.ResourceDiff, i interface{}) error { + if !rd.HasChange("item") { + return nil + } + + keys := map[string]bool{} + metadata, ok := rd.Get("item").([]any) + if !ok { + return xerrors.Errorf("unexpected type %T for items, expected []any", rd.Get("metadata")) + } + for _, t := range metadata { + obj, ok := t.(map[string]any) + if !ok { + return xerrors.Errorf("unexpected type %T for item, expected map[string]any", t) + } + key, ok := obj["key"].(string) + if !ok { + return xerrors.Errorf("unexpected type %T for items 'key' attribute, expected string", obj["key"]) + } + if keys[key] { + return xerrors.Errorf("duplicate resource metadata key %q", key) + } + keys[key] = true + } + return nil + }, } } diff --git a/provider/metadata_test.go b/provider/metadata_test.go index 0243f48d..14cdf5bc 100644 --- a/provider/metadata_test.go +++ b/provider/metadata_test.go @@ -123,7 +123,8 @@ func TestMetadataDuplicateKeys(t *testing.T) { } } `, - ExpectError: regexp.MustCompile("duplicate metadata key"), + PlanOnly: true, + ExpectError: regexp.MustCompile("duplicate resource metadata key"), }}, }) } diff --git a/provider/provider.go b/provider/provider.go index 1a37b706..1d78f2dd 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -97,14 +97,8 @@ func populateIsNull(resourceData *schema.ResourceData) (result interface{}, err items := rawPlan.GetAttr("item").AsValueSlice() var resultItems []interface{} - itemKeys := map[string]struct{}{} for _, item := range items { key := valueAsString(item.GetAttr("key")) - _, exists := itemKeys[key] - if exists { - return nil, xerrors.Errorf("duplicate metadata key %q", key) - } - itemKeys[key] = struct{}{} resultItem := map[string]interface{}{ "key": key, "value": valueAsString(item.GetAttr("value")), From 0da135c0207017ae4c8329ee2b3fea5d1cc1b662 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 6 Sep 2024 10:48:17 +0100 Subject: [PATCH 102/173] chore(integration): cleanup on interrupt (#283) --- integration/integration_test.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/integration/integration_test.go b/integration/integration_test.go index b7132d18..c98a45eb 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -7,10 +7,12 @@ import ( "fmt" "io" "os" + "os/signal" "path/filepath" "runtime" "strconv" "strings" + "sync" "testing" "time" @@ -203,12 +205,24 @@ func setup(ctx context.Context, t *testing.T, name, coderImg, coderVersion strin require.NoError(t, err, "create test deployment") t.Logf("created container %s\n", ctr.ID) - t.Cleanup(func() { // Make sure we clean up after ourselves. - // TODO: also have this execute if you Ctrl+C! + var cleanupOnce sync.Once + removeContainer := func() { t.Logf("stopping container %s\n", ctr.ID) _ = cli.ContainerRemove(ctx, ctr.ID, container.RemoveOptions{ Force: true, }) + } + // Ensure the container is cleaned up if you press Ctrl+C. + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt) + go func() { + <-sigCh + cleanupOnce.Do(removeContainer) + os.Exit(1) + }() + + t.Cleanup(func() { // Make sure we clean up after ourselves. + cleanupOnce.Do(removeContainer) }) err = cli.ContainerStart(ctx, ctr.ID, container.StartOptions{}) From cd7945d11ca71c2a0ca46abefd925c32ca153a9f Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 6 Sep 2024 10:53:19 +0100 Subject: [PATCH 103/173] feat: add 'hidden' field to 'coder_app' provider (#276) * feat: add 'hidden' field to 'coder_app' provider * fix: run 'make gen' * test: add integration test for 'coder_app.hidden' * fix: warn on 'hidden' being used with conflicting fields --- docs/resources/app.md | 1 + integration/coder-app-hidden/main.tf | 62 +++++++++++++++++++++++ integration/integration_test.go | 9 ++++ provider/app.go | 38 ++++++++++++++- provider/app_test.go | 73 ++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 integration/coder-app-hidden/main.tf diff --git a/docs/resources/app.md b/docs/resources/app.md index 1cb5d08b..ab44bede 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -63,6 +63,7 @@ resource "coder_app" "vim" { - `display_name` (String) A display name to identify the app. Defaults to the slug. - `external` (Boolean) Specifies whether `url` is opened on the client machine instead of proxied through the workspace. - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) +- `hidden` (Boolean) Determines if the app is visible in the UI. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). - `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). diff --git a/integration/coder-app-hidden/main.tf b/integration/coder-app-hidden/main.tf new file mode 100644 index 00000000..6376b25d --- /dev/null +++ b/integration/coder-app-hidden/main.tf @@ -0,0 +1,62 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_app" "hidden" { + agent_id = coder_agent.dev.id + slug = "hidden" + share = "owner" + hidden = true +} + +resource "coder_app" "visible" { + agent_id = coder_agent.dev.id + slug = "visible" + share = "owner" + hidden = false +} + +resource "coder_app" "defaulted" { + agent_id = coder_agent.dev.id + slug = "defaulted" + share = "owner" +} + +locals { + # NOTE: these must all be strings in the output + output = { + "coder_app.hidden.hidden" = tostring(coder_app.hidden.hidden) + "coder_app.visible.hidden" = tostring(coder_app.visible.hidden) + "coder_app.defaulted.hidden" = tostring(coder_app.defaulted.hidden) + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} + diff --git a/integration/integration_test.go b/integration/integration_test.go index c98a45eb..26b9544a 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -114,6 +114,15 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, }, }, + { + name: "coder-app-hidden", + minVersion: "v0.0.0", + expectedOutput: map[string]string{ + "coder_app.hidden.hidden": "true", + "coder_app.visible.hidden": "false", + "coder_app.defaulted.hidden": "false", + }, + }, } { tt := tt t.Run(tt.name, func(t *testing.T) { diff --git a/provider/app.go b/provider/app.go index 754b0e2a..10f946c7 100644 --- a/provider/app.go +++ b/provider/app.go @@ -30,7 +30,36 @@ func appResource() *schema.Resource { Description: "Use this resource to define shortcuts to access applications in a workspace.", CreateContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { resourceData.SetId(uuid.NewString()) - return nil + + diags := diag.Diagnostics{} + + hiddenData := resourceData.Get("hidden") + if hidden, ok := hiddenData.(bool); !ok { + return diag.Errorf("hidden should be a bool") + } else if hidden { + if _, ok := resourceData.GetOk("display_name"); ok { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "`display_name` set when app is hidden", + }) + } + + if _, ok := resourceData.GetOk("icon"); ok { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "`icon` set when app is hidden", + }) + } + + if _, ok := resourceData.GetOk("order"); ok { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "`order` set when app is hidden", + }) + } + } + + return diags }, ReadContext: func(c context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { return nil @@ -187,6 +216,13 @@ func appResource() *schema.Resource { ForceNew: true, Optional: true, }, + "hidden": { + Type: schema.TypeBool, + Description: "Determines if the app is visible in the UI.", + Default: false, + ForceNew: true, + Optional: true, + }, }, } } diff --git a/provider/app_test.go b/provider/app_test.go index f17513e1..80f1df14 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -45,6 +45,7 @@ func TestApp(t *testing.T) { threshold = 6 } order = 4 + hidden = false } `, Check: func(state *terraform.State) error { @@ -66,6 +67,7 @@ func TestApp(t *testing.T) { "healthcheck.0.interval", "healthcheck.0.threshold", "order", + "hidden", } { value := resource.Primary.Attributes[key] t.Logf("%q = %q", key, value) @@ -246,4 +248,75 @@ func TestApp(t *testing.T) { }) } }) + + t.Run("Hidden", func(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + config string + hidden bool + }{{ + name: "Is Hidden", + config: ` + provider "coder" {} + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + } + resource "coder_app" "test" { + agent_id = coder_agent.dev.id + slug = "test" + display_name = "Testing" + url = "https://google.com" + external = true + hidden = true + } + `, + hidden: true, + }, { + name: "Is Not Hidden", + config: ` + provider "coder" {} + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + } + resource "coder_app" "test" { + agent_id = coder_agent.dev.id + slug = "test" + display_name = "Testing" + url = "https://google.com" + external = true + hidden = false + } + `, + hidden: false, + }} + for _, tc := range cases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: tc.config, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 2) + resource := state.Modules[0].Resources["coder_app.test"] + require.NotNil(t, resource) + require.Equal(t, strconv.FormatBool(tc.hidden), resource.Primary.Attributes["hidden"]) + return nil + }, + ExpectError: nil, + }}, + }) + }) + } + }) + } From 332f8ae7845eb0399151ffa4d27a6dc493840ae0 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 9 Sep 2024 13:10:06 +0100 Subject: [PATCH 104/173] docs: document minimum version required for 'hidden' attribute (#285) * docs: document minimum version required for 'hidden' attribute * fix: capitalize coder Co-authored-by: Cian Johnston * fix: apply 'make gen' --------- Co-authored-by: Cian Johnston --- docs/resources/app.md | 2 +- provider/app.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resources/app.md b/docs/resources/app.md index ab44bede..6b8e99f4 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -63,7 +63,7 @@ resource "coder_app" "vim" { - `display_name` (String) A display name to identify the app. Defaults to the slug. - `external` (Boolean) Specifies whether `url` is opened on the client machine instead of proxied through the workspace. - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) -- `hidden` (Boolean) Determines if the app is visible in the UI. +- `hidden` (Boolean) Determines if the app is visible in the UI (minimum Coder version: v2.16). - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). - `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). diff --git a/provider/app.go b/provider/app.go index 10f946c7..3fd71692 100644 --- a/provider/app.go +++ b/provider/app.go @@ -218,7 +218,7 @@ func appResource() *schema.Resource { }, "hidden": { Type: schema.TypeBool, - Description: "Determines if the app is visible in the UI.", + Description: "Determines if the app is visible in the UI (minimum Coder version: v2.16).", Default: false, ForceNew: true, Optional: true, From 2598aa7c653b2e8c512ce5789106f07d0a51251f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20L=C3=B3pez=20Mareque?= Date: Wed, 11 Sep 2024 15:04:22 +0200 Subject: [PATCH 105/173] Add login_type to coder_workspace_owner data source #235 (#287) * feat: add login_type to coder_workspace_owner data source * feat: remove types check * feat: update integration test * feat: run linter * feat: set empty string as the default value for the login type * feat: update integration test * feat: add a warning when the CODER_WORKSPACE_OWNER_LOGIN_TYPE is not set * feat: create a new diags variable * feat: add missing comma * feat: add missing parenthesis * feat: fix typo in summary field Co-authored-by: Cian Johnston --------- Co-authored-by: Cian Johnston --- docs/data-sources/workspace_owner.md | 1 + integration/integration_test.go | 1 + integration/workspace-owner/main.tf | 1 + provider/workspace_owner.go | 17 ++++++++++++++++- provider/workspace_owner_test.go | 5 +++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index 1c64ea50..fbe4f205 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -50,6 +50,7 @@ resource "coder_env" "git_author_email" { - `full_name` (String) The full name of the user. - `groups` (List of String) The groups of which the user is a member. - `id` (String) The UUID of the workspace owner. +- `login_type` (String) The type of login the user has. - `name` (String) The username of the user. - `oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. - `session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated every time a workspace is started. diff --git a/integration/integration_test.go b/integration/integration_test.go index 26b9544a..dc3d5c98 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -112,6 +112,7 @@ func TestIntegration(t *testing.T) { "workspace_owner.session_token": `.+`, "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, + "workspace_owner.login_type": ``, }, }, { diff --git a/integration/workspace-owner/main.tf b/integration/workspace-owner/main.tf index 2be11d8e..fd923a3d 100644 --- a/integration/workspace-owner/main.tf +++ b/integration/workspace-owner/main.tf @@ -39,6 +39,7 @@ locals { "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, } } diff --git a/provider/workspace_owner.go b/provider/workspace_owner.go index 13e36187..c51751b0 100644 --- a/provider/workspace_owner.go +++ b/provider/workspace_owner.go @@ -15,6 +15,8 @@ func workspaceOwnerDataSource() *schema.Resource { return &schema.Resource{ Description: "Use this data source to fetch information about the workspace owner.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + diags := diag.Diagnostics{} + if idStr := os.Getenv("CODER_WORKSPACE_OWNER_ID"); idStr != "" { rd.SetId(idStr) } else { @@ -53,7 +55,15 @@ func workspaceOwnerDataSource() *schema.Resource { _ = rd.Set("session_token", os.Getenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN")) _ = rd.Set("oidc_access_token", os.Getenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN")) - return nil + if os.Getenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE") == "" { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "WARNING: The CODER_WORKSPACE_OWNER_LOGIN_TYPE env variable is not set", + }) + } + _ = rd.Set("login_type", os.Getenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE")) + + return diags }, Schema: map[string]*schema.Schema{ "id": { @@ -107,6 +117,11 @@ func workspaceOwnerDataSource() *schema.Resource { "This is only available if the workspace owner authenticated with OpenID Connect. " + "If a valid token cannot be obtained, this value will be an empty string.", }, + "login_type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of login the user has.", + }, }, } } diff --git a/provider/workspace_owner_test.go b/provider/workspace_owner_test.go index 90839cfc..91f47ea8 100644 --- a/provider/workspace_owner_test.go +++ b/provider/workspace_owner_test.go @@ -35,6 +35,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", `supersecret`) t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", `alsosupersecret`) + t.Setenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE", `github`) resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ @@ -63,6 +64,8 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { assert.Equal(t, `group2`, attrs["groups.1"]) assert.Equal(t, `supersecret`, attrs["session_token"]) assert.Equal(t, `alsosupersecret`, attrs["oidc_access_token"]) + assert.Equal(t, `github`, attrs["login_type"]) + return nil }, }}, @@ -80,6 +83,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { "CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY", "CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY", + "CODER_WORKSPACE_OWNER_LOGIN_TYPE", } { // https://github.com/golang/go/issues/52817 t.Setenv(v, "") os.Unsetenv(v) @@ -111,6 +115,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { assert.Empty(t, attrs["groups.0"]) assert.Empty(t, attrs["session_token"]) assert.Empty(t, attrs["oidc_access_token"]) + assert.Empty(t, attrs["login_type"]) return nil }, }}, From 1e8489449a22dbb1e59dcbf0209508004fc98311 Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Tue, 24 Sep 2024 15:56:14 +0400 Subject: [PATCH 106/173] fix: update to terraform-plugin-sdk v2.34.0 (#290) --- go.mod | 44 ++++--- go.sum | 218 ++++++++++++------------------- provider/agent_test.go | 57 +++----- provider/app_test.go | 26 ++-- provider/env_test.go | 26 ++-- provider/examples_test.go | 8 +- provider/externalauth_test.go | 15 +-- provider/metadata_test.go | 16 +-- provider/parameter_test.go | 10 +- provider/provider_test.go | 14 +- provider/provisioner_test.go | 9 +- provider/script_test.go | 26 ++-- provider/workspace_owner_test.go | 14 +- provider/workspace_tags_test.go | 9 +- provider/workspace_test.go | 21 +-- 15 files changed, 185 insertions(+), 328 deletions(-) diff --git a/go.mod b/go.mod index 17d00108..ec54a5e1 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 @@ -20,15 +20,17 @@ require ( require ( github.com/Masterminds/semver v1.5.0 // indirect - github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -38,24 +40,24 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.2.1 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.4 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.4.0 // indirect - github.com/hashicorp/hcl/v2 v2.13.0 // indirect + github.com/hashicorp/hc-install v0.6.4 // indirect + github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.17.2 // indirect - github.com/hashicorp/terraform-json v0.14.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.12.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect - github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect - github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/hashicorp/terraform-exec v0.21.0 // indirect + github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/hashicorp/terraform-plugin-go v0.23.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect + github.com/hashicorp/terraform-registry-address v0.2.3 // indirect + github.com/hashicorp/terraform-svchost v0.1.1 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect github.com/kr/pretty v0.3.0 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -70,9 +72,9 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect - github.com/vmihailenco/tagparser v0.1.1 // indirect - github.com/zclconf/go-cty v1.10.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect @@ -81,9 +83,11 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 // indirect golang.org/x/crypto v0.24.0 // indirect golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.64.1 // indirect diff --git a/go.sum b/go.sum index 95a4084f..ccbb2a1f 100644 --- a/go.sum +++ b/go.sum @@ -1,31 +1,29 @@ -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= -github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -37,22 +35,19 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= -github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= -github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= -github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -62,18 +57,15 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -86,82 +78,71 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= -github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= -github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= -github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= -github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= -github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= +github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= +github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= +github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= +github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go= -github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= -github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= -github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= -github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw= -github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M= -github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= -github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0 h1:+KxZULPsbjpAVoP0WNj/8aVW6EqpcX5JcUcQ5wl7Da4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.20.0/go.mod h1:DwGJG3KNxIPluVk6hexvDfYR/MS/eKGpiztJoT3Bbbw= -github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg= -github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= -github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= -github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= +github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= +github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= +github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= +github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= +github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= +github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= +github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= +github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= +github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 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/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/masterminds/semver v1.5.0 h1:hTxJTTY7tjvnWMrl08O6u3G6BLlKVwxSz01lVac9P8U= github.com/masterminds/semver v1.5.0/go.mod h1:s7KNT9fnd7edGzwwP7RBX4H0v/CYd5qdOLfkL1V75yg= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -176,17 +157,15 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= -github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= 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.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -196,39 +175,31 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= -github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= @@ -246,13 +217,9 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= @@ -263,50 +230,35 @@ golang.org/x/mod v0.3.0/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.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/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-20200301022130-244492dfa37a/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-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -314,7 +266,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= @@ -326,14 +277,14 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn 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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= @@ -345,18 +296,11 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/provider/agent_test.go b/provider/agent_test.go index 91c708ca..d40caf56 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -6,20 +6,15 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" - - "github.com/coder/terraform-provider-coder/provider" ) func TestAgent(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -110,10 +105,8 @@ func TestAgent_StartupScriptBehavior(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: tc.Config, ExpectError: tc.ExpectError, @@ -136,10 +129,8 @@ func TestAgent_StartupScriptBehavior(t *testing.T) { func TestAgent_Instance(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -177,10 +168,8 @@ func TestAgent_Instance(t *testing.T) { func TestAgent_Metadata(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -225,10 +214,8 @@ func TestAgent_Metadata(t *testing.T) { func TestAgent_MetadataDuplicateKeys(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -263,10 +250,8 @@ func TestAgent_DisplayApps(t *testing.T) { t.Parallel() t.Run("OK", func(t *testing.T) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ // Test the fields with non-default values. Config: ` @@ -316,10 +301,8 @@ func TestAgent_DisplayApps(t *testing.T) { t.Run("Subset", func(t *testing.T) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ // Test the fields with non-default values. Config: ` @@ -363,10 +346,8 @@ func TestAgent_DisplayApps(t *testing.T) { // Assert all the defaults are set correctly. t.Run("Omitted", func(t *testing.T) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -408,10 +389,8 @@ func TestAgent_DisplayApps(t *testing.T) { t.Run("InvalidApp", func(t *testing.T) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ // Test the fields with non-default values. Config: ` diff --git a/provider/app_test.go b/provider/app_test.go index 80f1df14..6a17ca0c 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -6,9 +6,7 @@ import ( "strconv" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" ) @@ -20,10 +18,8 @@ func TestApp(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -129,10 +125,8 @@ func TestApp(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: tc.config, Check: func(state *terraform.State) error { @@ -235,10 +229,8 @@ func TestApp(t *testing.T) { } resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: config, Check: checkFn, @@ -298,10 +290,8 @@ func TestApp(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: tc.config, Check: func(state *terraform.State) error { diff --git a/provider/env_test.go b/provider/env_test.go index 66925f5e..a5892254 100644 --- a/provider/env_test.go +++ b/provider/env_test.go @@ -4,11 +4,9 @@ import ( "regexp" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/stretchr/testify/require" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) @@ -16,10 +14,8 @@ func TestEnv(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -53,10 +49,8 @@ func TestEnvEmptyValue(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -89,10 +83,8 @@ func TestEnvBadName(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -111,10 +103,8 @@ func TestEnvNoName(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { diff --git a/provider/examples_test.go b/provider/examples_test.go index ab68954b..c6931ae3 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -6,9 +6,7 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/stretchr/testify/require" - "github.com/coder/terraform-provider-coder/provider" ) func TestExamples(t *testing.T) { @@ -29,10 +27,8 @@ func TestExamples(t *testing.T) { func resourceTest(t *testing.T, testDir string) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: mustReadFile(t, fmt.Sprintf("../examples/data-sources/%s/data-source.tf", testDir)), }}, diff --git a/provider/externalauth_test.go b/provider/externalauth_test.go index 826f0a91..4c328a45 100644 --- a/provider/externalauth_test.go +++ b/provider/externalauth_test.go @@ -3,10 +3,7 @@ package provider_test import ( "testing" - "github.com/coder/terraform-provider-coder/provider" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" @@ -16,10 +13,8 @@ func TestExternalAuth(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -48,10 +43,8 @@ func TestOptionalExternalAuth(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { diff --git a/provider/metadata_test.go b/provider/metadata_test.go index 14cdf5bc..3164e65b 100644 --- a/provider/metadata_test.go +++ b/provider/metadata_test.go @@ -4,21 +4,16 @@ import ( "regexp" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" ) func TestMetadata(t *testing.T) { t.Parallel() - prov := provider.New() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": prov, - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -95,12 +90,9 @@ func TestMetadata(t *testing.T) { func TestMetadataDuplicateKeys(t *testing.T) { t.Parallel() - prov := provider.New() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": prov, - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 05d3604b..fc814cba 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -4,11 +4,11 @@ import ( "regexp" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" + + "github.com/coder/terraform-provider-coder/provider" ) func TestParameter(t *testing.T) { @@ -660,10 +660,8 @@ data "coder_parameter" "region" { t.Run(tc.Name, func(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: tc.Config, ExpectError: tc.ExpectError, diff --git a/provider/provider_test.go b/provider/provider_test.go index 742eb30b..3367e7f4 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -24,10 +24,8 @@ func TestProvider(t *testing.T) { func TestProviderEmpty(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" {} @@ -46,3 +44,11 @@ func TestProviderEmpty(t *testing.T) { }}, }) } + +func coderFactory() map[string]func() (*schema.Provider, error) { + return map[string]func() (*schema.Provider, error){ + "coder": func() (*schema.Provider, error) { + return provider.New(), nil + }, + } +} diff --git a/provider/provisioner_test.go b/provider/provisioner_test.go index f1521ef9..53295bcd 100644 --- a/provider/provisioner_test.go +++ b/provider/provisioner_test.go @@ -4,9 +4,7 @@ import ( "runtime" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" ) @@ -14,10 +12,8 @@ import ( func TestProvisioner(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -42,4 +38,3 @@ func TestProvisioner(t *testing.T) { }}, }) } - diff --git a/provider/script_test.go b/provider/script_test.go index 9b6bd570..37f1a819 100644 --- a/provider/script_test.go +++ b/provider/script_test.go @@ -4,11 +4,9 @@ import ( "regexp" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/stretchr/testify/require" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) @@ -16,10 +14,8 @@ func TestScript(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -55,10 +51,8 @@ func TestScriptNeverRuns(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -78,10 +72,8 @@ func TestScriptStartBlocksLoginRequiresRunOnStart(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -98,10 +90,8 @@ func TestScriptStartBlocksLoginRequiresRunOnStart(t *testing.T) { }}, }) resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { diff --git a/provider/workspace_owner_test.go b/provider/workspace_owner_test.go index 91f47ea8..ad371570 100644 --- a/provider/workspace_owner_test.go +++ b/provider/workspace_owner_test.go @@ -4,9 +4,7 @@ import ( "os" "testing" - "github.com/coder/terraform-provider-coder/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -38,10 +36,8 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE", `github`) resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" {} @@ -90,10 +86,8 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { } resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" {} diff --git a/provider/workspace_tags_test.go b/provider/workspace_tags_test.go index 2d0f1c49..95949562 100644 --- a/provider/workspace_tags_test.go +++ b/provider/workspace_tags_test.go @@ -4,19 +4,14 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" - - "github.com/coder/terraform-provider-coder/provider" ) func TestWorkspaceTags(t *testing.T) { resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { diff --git a/provider/workspace_test.go b/provider/workspace_test.go index 12d5210b..e82a1005 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -5,12 +5,9 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/coder/terraform-provider-coder/provider" ) func TestWorkspace(t *testing.T) { @@ -19,10 +16,8 @@ func TestWorkspace(t *testing.T) { t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -57,10 +52,8 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { @@ -96,10 +89,8 @@ func TestWorkspace_MissingTemplateName(t *testing.T) { t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") resource.Test(t, resource.TestCase{ - Providers: map[string]*schema.Provider{ - "coder": provider.New(), - }, - IsUnitTest: true, + ProviderFactories: coderFactory(), + IsUnitTest: true, Steps: []resource.TestStep{{ Config: ` provider "coder" { From 9c7b364131ca0359b4ea927ebf35df8386f6242c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:55:07 +0500 Subject: [PATCH 107/173] build(deps): Bump contributor-assistant/github-action from 2.5.1 to 2.6.0 (#289) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 494dddc8..5fdf7482 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.5.1 + uses: contributor-assistant/github-action@v2.6.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From f4d4fc111a328083be8ed6ff92fe8f1d7cf8801c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 15:33:49 +0500 Subject: [PATCH 108/173] build(deps): Bump contributor-assistant/github-action from 2.6.0 to 2.6.1 (#291) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 5fdf7482..71c2e905 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: "CLA Assistant" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@v2.6.0 + uses: contributor-assistant/github-action@v2.6.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From 2863913f28c633f636ed03a59c18f20da18580ff Mon Sep 17 00:00:00 2001 From: Spike Curtis Date: Mon, 14 Oct 2024 11:20:40 +0400 Subject: [PATCH 109/173] chore: add http/pprof server over unix socket for debug (#295) * chore: add http/pprof server over unix socket for debug Signed-off-by: Spike Curtis * remove old pprof file without checking if it exists Signed-off-by: Spike Curtis --------- Signed-off-by: Spike Curtis --- main.go | 1 + pprof_unix.go | 42 ++++++++++++++++++++++++++++++++++++++++++ pprof_windows.go | 6 ++++++ 3 files changed, 49 insertions(+) create mode 100644 pprof_unix.go create mode 100644 pprof_windows.go diff --git a/main.go b/main.go index 000436a3..a16c9951 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs func main() { + servePprof() plugin.Serve(&plugin.ServeOpts{ ProviderFunc: provider.New, }) diff --git a/pprof_unix.go b/pprof_unix.go new file mode 100644 index 00000000..717bc01b --- /dev/null +++ b/pprof_unix.go @@ -0,0 +1,42 @@ +//go:build !windows + +package main + +import ( + "net" + "net/http" + "net/http/pprof" + "os" +) + +// servePprof starts an HTTP server running the pprof goroutine handler on a local unix domain socket. As described in +// https://github.com/coder/coder/issues/14726 it appears this process is sometimes hanging, unable to exit cleanly, +// and this prevents additional Coder builds that try to reinstall this provider. A goroutine dump should allow us to +// determine what is hanging. +// +// This function is best-effort, and just returns early if we fail to set up the directory/listener. We don't want to +// block the normal functioning of the provider. +func servePprof() { + // Coder runs terraform in a per-build subdirectory of the work directory. The per-build subdirectory uses a + // generated name and is deleted at the end of a build, so we want to place our unix socket up one directory level + // in the provisionerd work directory, so we can connect to it from provisionerd. + err := os.Mkdir("../.coder", 0o700) + if err != nil && !os.IsExist(err) { + return + } + + // remove the old file, if it exists. It's probably from the last run of the provider + if err = os.Remove("../.coder/pprof"); err != nil && !os.IsNotExist(err) { + return + } + l, err := net.Listen("unix", "../.coder/pprof") + if err != nil { + return + } + mux := http.NewServeMux() + mux.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) + srv := http.Server{Handler: mux} + go srv.Serve(l) + // We just leave the server and domain socket up forever. Go programs exit when the `main()` function returns, so + // this won't block exiting, and it ensures the pprof server stays up for the entire lifetime of the provider. +} diff --git a/pprof_windows.go b/pprof_windows.go new file mode 100644 index 00000000..05cd3143 --- /dev/null +++ b/pprof_windows.go @@ -0,0 +1,6 @@ +//go:build windows + +package main + +// servePprof is not supported on Windows +func servePprof() {} From 224049576dd47cb724adac4958293bfca6222c78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:07:34 +0500 Subject: [PATCH 110/173] build(deps): Bump goreleaser/goreleaser-action from 6.0.0 to 6.1.0 (#301) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6bf1284c..0f54844a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6.0.0 + uses: goreleaser/goreleaser-action@v6.1.0 with: version: latest args: release --clean From 493a0f18a5383db9c2eaf8d1bffd8b8caf978507 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:07:49 +0500 Subject: [PATCH 111/173] build(deps): Bump crazy-max/ghaction-import-gpg from 6.1.0 to 6.2.0 (#298) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f54844a..5aa16488 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v6.1.0 + uses: crazy-max/ghaction-import-gpg@v6.2.0 with: # These secrets will need to be configured for the repository: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} From 0fc111255226e66a78829a62afa6f167637e4fe9 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Tue, 26 Nov 2024 17:54:20 +0500 Subject: [PATCH 112/173] docs: v1 to v2 upgrade guide (#259) --- docs/guides/version-2-upgrade.md | 101 +++++++++++++++++++++ docs/index.md | 6 +- go.mod | 2 +- templates/guides/version-2-upgrade.md.tmpl | 101 +++++++++++++++++++++ templates/index.md.tmpl | 6 +- 5 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 docs/guides/version-2-upgrade.md create mode 100644 templates/guides/version-2-upgrade.md.tmpl diff --git a/docs/guides/version-2-upgrade.md b/docs/guides/version-2-upgrade.md new file mode 100644 index 00000000..49e262e1 --- /dev/null +++ b/docs/guides/version-2-upgrade.md @@ -0,0 +1,101 @@ +--- +page_title: "Terraform Coder Provider Version 2 Upgrade Guide" +--- + +# Terraform Coder Provider Version 2 Upgrade Guide + +Version 2.0.0 of the Coder provider for Terraform is a major release that introduces some changes that you will need to consider when upgrading. +This guide is intended to help with the process, and focuses only on the changes from version 1.X to version 2.0.0. + +!> Using Version 2.0.0 of the Coder provider requires Coder Server version [`2.18.0`](https://github.com/coder/coder/releases/tag/v2.18.0) or later. + +Upgrade topics: + +- [Provider Version Configuration](#provider-version-configuration) +- [Provider Arguments](#provider-arguments) +- [Data Source: coder_git_auth --> coder_external_auth](#data-source-coder_git_auth) +- [Data Source: coder_workspace](#data-source-coder_workspace) + +## Provider Version Configuration + +-> Before upgrading to version 2.0.0, please first upgrade to the most recent 1.X version and ensure that your environment successfully runs [`terraform plan`](https://developer.hashicorp.com/terraform/cli/commands/plan) without unexpected changes or deprecation notices. + +We highly recommend using [version constraints](https://developer.hashicorp.com/terraform/language/providers/requirements#version-constraints) when configuring Terraform providers. + + +For example, given the previous configuration: + +```terraform +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 1.0.0" + } + } +} + +provider "coder" { + feature_use_managed_variables = true +} +``` + +Update to the latest 2.X version: + +```terraform +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 2.0.0" + } + } +} + +provider "coder" {} +``` + +## Provider Arguments + +Version 2.0.0 removes the [`feature_use_managed_variables`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs#feature_use_managed_variables-1) argument from the `provider` block. + + +## Data Source: [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) + +If you are using this data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. + +For example, given the previous configuration: + +```terraform +data "coder_git_auth" "example" { + id = "example" +} +``` + +Update to the new data source: + +```terraform +data "coder_external_auth" "example" { + id = "example" +} +``` + +## Data Source: [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) + +If you are using the `owner` properties of the `coder_workspace` data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. + +Update your Terraform configuration to use the `coder_workspace_owner` data source instead and update the following attributes: + +```terraform +data "coder_workspace_owner" "me" {} +``` + +- Remove `owner_id` attribute. Use [`data.coder_workspace_owner.me.id`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#id) instead. +- Remove `owner` attribute. Use [`data.coder_workspace_owner.me.name`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#name) instead. +- Remove `owner_name` attribute. Use [`data.coder_workspace_owner.me.full_name`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#full_name) instead. +- Remove `owner_email` attribute. Use [`data.coder_workspace_owner.me.email`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#email) instead. +- Remove `owner_groups` attribute. Use [`data.coder_workspace_owner.me.groups`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#groups) instead. +- Remove `owner_oidc_access_token` attribute. Use [`data.coder_workspace_owner.me.oidc_access_token`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#oidc_access_token) instead. +- Remove `owner_session_token` attribute. Use [`data.coder_workspace_owner.me.session_token`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#session_token) instead. + +->While we do not anticipate these changes to affect existing resources, we strongly advice reviewing the plan produced by Terraform to ensure no resources are accidentally removed or altered in an undesired way. If you encounter any unexpected behavior, please report it by opening a GitHub [issue](https://github.com/coder/terraform-provider-coder/issues). \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 7ce115a7..ec7be2d8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,11 @@ description: |- # Coder Provider -Terraform provider for managing Coder [templates](https://coder.com/docs/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/workspaces). +Terraform provider for managing Coder [templates](https://coder.com/docs/admin/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/user-guides/workspace-management). + +-> Requires Coder [v2.18.0](https://github.com/coder/coder/releases/tag/v2.18.0) or later. + +!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/codercom/coder/latest/docs/guides/version-2-upgrade) to update your code. ## Example diff --git a/go.mod b/go.mod index ec54a5e1..f4f40b67 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/coder/terraform-provider-coder go 1.22 -toolchain go1.22.3 +toolchain go1.22.9 require ( github.com/docker/docker v26.1.5+incompatible diff --git a/templates/guides/version-2-upgrade.md.tmpl b/templates/guides/version-2-upgrade.md.tmpl new file mode 100644 index 00000000..49e262e1 --- /dev/null +++ b/templates/guides/version-2-upgrade.md.tmpl @@ -0,0 +1,101 @@ +--- +page_title: "Terraform Coder Provider Version 2 Upgrade Guide" +--- + +# Terraform Coder Provider Version 2 Upgrade Guide + +Version 2.0.0 of the Coder provider for Terraform is a major release that introduces some changes that you will need to consider when upgrading. +This guide is intended to help with the process, and focuses only on the changes from version 1.X to version 2.0.0. + +!> Using Version 2.0.0 of the Coder provider requires Coder Server version [`2.18.0`](https://github.com/coder/coder/releases/tag/v2.18.0) or later. + +Upgrade topics: + +- [Provider Version Configuration](#provider-version-configuration) +- [Provider Arguments](#provider-arguments) +- [Data Source: coder_git_auth --> coder_external_auth](#data-source-coder_git_auth) +- [Data Source: coder_workspace](#data-source-coder_workspace) + +## Provider Version Configuration + +-> Before upgrading to version 2.0.0, please first upgrade to the most recent 1.X version and ensure that your environment successfully runs [`terraform plan`](https://developer.hashicorp.com/terraform/cli/commands/plan) without unexpected changes or deprecation notices. + +We highly recommend using [version constraints](https://developer.hashicorp.com/terraform/language/providers/requirements#version-constraints) when configuring Terraform providers. + + +For example, given the previous configuration: + +```terraform +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 1.0.0" + } + } +} + +provider "coder" { + feature_use_managed_variables = true +} +``` + +Update to the latest 2.X version: + +```terraform +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 2.0.0" + } + } +} + +provider "coder" {} +``` + +## Provider Arguments + +Version 2.0.0 removes the [`feature_use_managed_variables`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs#feature_use_managed_variables-1) argument from the `provider` block. + + +## Data Source: [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) + +If you are using this data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. + +For example, given the previous configuration: + +```terraform +data "coder_git_auth" "example" { + id = "example" +} +``` + +Update to the new data source: + +```terraform +data "coder_external_auth" "example" { + id = "example" +} +``` + +## Data Source: [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) + +If you are using the `owner` properties of the `coder_workspace` data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. + +Update your Terraform configuration to use the `coder_workspace_owner` data source instead and update the following attributes: + +```terraform +data "coder_workspace_owner" "me" {} +``` + +- Remove `owner_id` attribute. Use [`data.coder_workspace_owner.me.id`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#id) instead. +- Remove `owner` attribute. Use [`data.coder_workspace_owner.me.name`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#name) instead. +- Remove `owner_name` attribute. Use [`data.coder_workspace_owner.me.full_name`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#full_name) instead. +- Remove `owner_email` attribute. Use [`data.coder_workspace_owner.me.email`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#email) instead. +- Remove `owner_groups` attribute. Use [`data.coder_workspace_owner.me.groups`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#groups) instead. +- Remove `owner_oidc_access_token` attribute. Use [`data.coder_workspace_owner.me.oidc_access_token`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#oidc_access_token) instead. +- Remove `owner_session_token` attribute. Use [`data.coder_workspace_owner.me.session_token`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#session_token) instead. + +->While we do not anticipate these changes to affect existing resources, we strongly advice reviewing the plan produced by Terraform to ensure no resources are accidentally removed or altered in an undesired way. If you encounter any unexpected behavior, please report it by opening a GitHub [issue](https://github.com/coder/terraform-provider-coder/issues). \ No newline at end of file diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index de4ec73e..be92b931 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -8,7 +8,11 @@ description: |- # Coder Provider -Terraform provider for managing Coder [templates](https://coder.com/docs/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/workspaces). +Terraform provider for managing Coder [templates](https://coder.com/docs/admin/templates), which are the underlying infrastructure for Coder [workspaces](https://coder.com/docs/user-guides/workspace-management). + +-> Requires Coder [v2.18.0](https://github.com/coder/coder/releases/tag/v2.18.0) or later. + +!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/codercom/coder/latest/docs/guides/version-2-upgrade) to update your code. ## Example From 701d7c888312a1867281f94f65a90777c036f1cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:02:14 +0500 Subject: [PATCH 113/173] build(deps): Bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#308) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f4f40b67..85487eb0 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/mod v0.20.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 diff --git a/go.sum b/go.sum index ccbb2a1f..bc8707fc 100644 --- a/go.sum +++ b/go.sum @@ -183,8 +183,8 @@ github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= From 86ca17f876c2b701916744179fdbc0073157878d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:27:33 +0500 Subject: [PATCH 114/173] build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 from 2.34.0 to 2.35.0 (#299) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Muhammad Atif Ali Co-authored-by: Muhammad Atif Ali --- go.mod | 39 +++++++++++++++---------------- go.sum | 74 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index 85487eb0..8ecff3e5 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,18 @@ module github.com/coder/terraform-provider-coder -go 1.22 - -toolchain go1.22.9 +go 1.22.9 require ( github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.20.0 + golang.org/x/mod v0.21.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) @@ -40,17 +38,18 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-plugin v1.6.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.6.4 // indirect - github.com/hashicorp/hcl/v2 v2.20.1 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/hc-install v0.9.0 // indirect + github.com/hashicorp/hcl/v2 v2.22.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect - github.com/hashicorp/terraform-json v0.22.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.23.0 // indirect + github.com/hashicorp/terraform-json v0.23.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.25.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect @@ -74,24 +73,24 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.64.1 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index bc8707fc..0a8cc437 100644 --- a/go.sum +++ b/go.sum @@ -82,33 +82,35 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= -github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= +github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= -github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= -github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= -github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= +github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= +github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= +github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= -github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= -github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= +github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= +github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -197,10 +199,10 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI 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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= @@ -221,30 +223,30 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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-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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -259,8 +261,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -268,8 +270,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -289,12 +291,12 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 73f18526e05e8e0ac5c556a67ba150c08b250da5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:51:55 +0500 Subject: [PATCH 115/173] build(deps): Bump golang.org/x/mod from 0.20.0 to 0.22.0 (#302) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8ecff3e5..609e1889 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.21.0 + golang.org/x/mod v0.22.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index 0a8cc437..524564a1 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXy 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= From f0607a6570a3911582547950366fe6235db349ab Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 10:19:28 +0000 Subject: [PATCH 116/173] ci: run integration tests against oldstable (#310) * feawt(scripts/coderversion): emit OLDSTABLE version * chore: update README to better illustrate testing on tip of main * chore(integration): add test for workspace owner being set * ci: run integration tests against oldstable --- .github/workflows/test.yml | 16 ++++++ README.md | 4 +- integration/integration_test.go | 28 +++++++++++ integration/workspace-owner-filled/main.tf | 58 ++++++++++++++++++++++ scripts/coderversion/main.go | 32 ++++++++++++ 5 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 integration/workspace-owner-filled/main.tf diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57faf626..eb521f88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,6 +38,14 @@ jobs: run: | go build -v . + - name: Run integration test (devel) + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder-preview" + CODER_VERSION: "latest" + run: | + go test -v ./integration + - name: Run integration test (mainline) timeout-minutes: 10 env: @@ -54,6 +62,14 @@ jobs: source <(go run ./scripts/coderversion) CODER_VERSION="${CODER_STABLE_VERSION}" go test -v ./integration + - name: Run integration test (oldstable) + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder" + run: | + source <(go run ./scripts/coderversion) + CODER_VERSION="${CODER_OLDSTABLE_VERSION}" go test -v ./integration + # run acceptance tests in a matrix with Terraform core versions test: name: Matrix Test diff --git a/README.md b/README.md index 2bceb73a..6f13efef 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,10 @@ To run these integration tests locally: 1. Pull the version of the Coder image you wish to test: ```console - docker pull ghcr.io/coder/coder:main-x.y.z-devel-abcd1234 + docker pull ghcr.io/coder/coder-preview:main-x.y.z-devel-abcd1234 ``` -1. Run `CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. +1. Run `CODER_IMAGE=ghcr.io/coder/coder-preview CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. > **Note:** you can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. > For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`. diff --git a/integration/integration_test.go b/integration/integration_test.go index dc3d5c98..f1596eee 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -115,6 +115,34 @@ func TestIntegration(t *testing.T) { "workspace_owner.login_type": ``, }, }, + { + name: "workspace-owner-filled", + minVersion: "v2.18.0", + expectedOutput: map[string]string{ + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": ``, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `workspace-owner`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, + "workspace_owner.email": `testing@coder\.com`, + "workspace_owner.full_name": `default`, + "workspace_owner.groups": `\[(\"Everyone\")?\]`, + "workspace_owner.id": `[a-zA-Z0-9-]+`, + "workspace_owner.name": `testing`, + "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration + "workspace_owner.session_token": `.+`, + "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, + "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, + "workspace_owner.login_type": `password`, + }, + }, { name: "coder-app-hidden", minVersion: "v0.0.0", diff --git a/integration/workspace-owner-filled/main.tf b/integration/workspace-owner-filled/main.tf new file mode 100644 index 00000000..fd923a3d --- /dev/null +++ b/integration/workspace-owner-filled/main.tf @@ -0,0 +1,58 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +// TODO: test coder_external_auth +// data coder_external_auth "me" {} +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +locals { + # NOTE: these must all be strings in the output + output = { + "provisioner.arch" : data.coder_provisioner.me.arch, + "provisioner.id" : data.coder_provisioner.me.id, + "provisioner.os" : data.coder_provisioner.me.os, + "workspace.access_port" : tostring(data.coder_workspace.me.access_port), + "workspace.access_url" : data.coder_workspace.me.access_url, + "workspace.id" : data.coder_workspace.me.id, + "workspace.name" : data.coder_workspace.me.name, + "workspace.start_count" : tostring(data.coder_workspace.me.start_count), + "workspace.template_id" : data.coder_workspace.me.template_id, + "workspace.template_name" : data.coder_workspace.me.template_name, + "workspace.template_version" : data.coder_workspace.me.template_version, + "workspace.transition" : data.coder_workspace.me.transition, + "workspace_owner.email" : data.coder_workspace_owner.me.email, + "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, + "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), + "workspace_owner.id" : data.coder_workspace_owner.me.id, + "workspace_owner.name" : data.coder_workspace_owner.me.name, + "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, + "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, + "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, + "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} diff --git a/scripts/coderversion/main.go b/scripts/coderversion/main.go index b6f57d4b..9b5f4c06 100644 --- a/scripts/coderversion/main.go +++ b/scripts/coderversion/main.go @@ -64,6 +64,38 @@ func main() { stable := fmt.Sprintf("v%d.%d.%d", stableVer.Major(), stableVer.Minor(), stableVer.Patch()) _, _ = fmt.Fprintf(os.Stdout, "CODER_STABLE_VERSION=%q\n", stable) + + expectedOldStableMinor := mainlineVer.Minor() - 2 + if expectedOldStableMinor < 0 { + expectedOldStableMinor = 0 + } + debug("expected old stable minor: %d\n", expectedStableMinor) + oldStableVer := semver.MustParse("v0.0.0") + for _, rel := range releases { + debug("check version %s\n", rel) + if rel == "" { + debug("ignoring untagged version %s\n", rel) + continue + } + + ver, err := semver.NewVersion(rel) + if err != nil { + debug("skipping invalid version %s\n", rel) + } + + if ver.Minor() != expectedOldStableMinor { + debug("skipping version %s\n", rel) + continue + } + + if ver.Compare(oldStableVer) > 0 { + oldStableVer = ver + continue + } + } + + oldStable := fmt.Sprintf("v%d.%d.%d", oldStableVer.Major(), oldStableVer.Minor(), oldStableVer.Patch()) + _, _ = fmt.Fprintf(os.Stdout, "CODER_OLDSTABLE_VERSION=%q\n", oldStable) } type release struct { From ceefe84eeb927d7650f541b1f951b44b718513c2 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 28 Nov 2024 16:07:46 +0500 Subject: [PATCH 117/173] fix: fix links in version 2 upgrade guide (#312) --- docs/guides/version-2-upgrade.md | 8 ++++---- docs/index.md | 2 +- templates/guides/version-2-upgrade.md.tmpl | 8 ++++---- templates/index.md.tmpl | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/guides/version-2-upgrade.md b/docs/guides/version-2-upgrade.md index 49e262e1..8c8233eb 100644 --- a/docs/guides/version-2-upgrade.md +++ b/docs/guides/version-2-upgrade.md @@ -1,8 +1,8 @@ --- -page_title: "Terraform Coder Provider Version 2 Upgrade Guide" +page_title: "Version 2 Upgrade Guide" --- -# Terraform Coder Provider Version 2 Upgrade Guide +# Version 2 Upgrade Guide Version 2.0.0 of the Coder provider for Terraform is a major release that introduces some changes that you will need to consider when upgrading. This guide is intended to help with the process, and focuses only on the changes from version 1.X to version 2.0.0. @@ -13,8 +13,8 @@ Upgrade topics: - [Provider Version Configuration](#provider-version-configuration) - [Provider Arguments](#provider-arguments) -- [Data Source: coder_git_auth --> coder_external_auth](#data-source-coder_git_auth) -- [Data Source: coder_workspace](#data-source-coder_workspace) +- [Data Source: [`coder_git_auth`](#data-source-coder_git_auth) +- [Data Source: [`coder_workspace`](#data-source-coder_workspace) ## Provider Version Configuration diff --git a/docs/index.md b/docs/index.md index ec7be2d8..c30f1477 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,7 @@ Terraform provider for managing Coder [templates](https://coder.com/docs/admin/t -> Requires Coder [v2.18.0](https://github.com/coder/coder/releases/tag/v2.18.0) or later. -!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/codercom/coder/latest/docs/guides/version-2-upgrade) to update your code. +!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/coder/coder/latest/docs/guides/version-2-upgrade) to update your code. ## Example diff --git a/templates/guides/version-2-upgrade.md.tmpl b/templates/guides/version-2-upgrade.md.tmpl index 49e262e1..8c8233eb 100644 --- a/templates/guides/version-2-upgrade.md.tmpl +++ b/templates/guides/version-2-upgrade.md.tmpl @@ -1,8 +1,8 @@ --- -page_title: "Terraform Coder Provider Version 2 Upgrade Guide" +page_title: "Version 2 Upgrade Guide" --- -# Terraform Coder Provider Version 2 Upgrade Guide +# Version 2 Upgrade Guide Version 2.0.0 of the Coder provider for Terraform is a major release that introduces some changes that you will need to consider when upgrading. This guide is intended to help with the process, and focuses only on the changes from version 1.X to version 2.0.0. @@ -13,8 +13,8 @@ Upgrade topics: - [Provider Version Configuration](#provider-version-configuration) - [Provider Arguments](#provider-arguments) -- [Data Source: coder_git_auth --> coder_external_auth](#data-source-coder_git_auth) -- [Data Source: coder_workspace](#data-source-coder_workspace) +- [Data Source: [`coder_git_auth`](#data-source-coder_git_auth) +- [Data Source: [`coder_workspace`](#data-source-coder_workspace) ## Provider Version Configuration diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index be92b931..efdaae96 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -12,7 +12,7 @@ Terraform provider for managing Coder [templates](https://coder.com/docs/admin/t -> Requires Coder [v2.18.0](https://github.com/coder/coder/releases/tag/v2.18.0) or later. -!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/codercom/coder/latest/docs/guides/version-2-upgrade) to update your code. +!> [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) and owner related fields of [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source have been removed. Follow the [Version 2 Upgrade Guide](https://registry.terraform.io/providers/coder/coder/latest/docs/guides/version-2-upgrade) to update your code. ## Example From b76e23221edb705517cd9864e3126a37e57b900e Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 11:08:19 +0000 Subject: [PATCH 118/173] fix(provider): remove warning diag if CODER_WORKSPACE_OWNER_LOGIN_TYPE is not set (#311) --- provider/workspace_owner.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/provider/workspace_owner.go b/provider/workspace_owner.go index c51751b0..52b1ef8c 100644 --- a/provider/workspace_owner.go +++ b/provider/workspace_owner.go @@ -55,13 +55,9 @@ func workspaceOwnerDataSource() *schema.Resource { _ = rd.Set("session_token", os.Getenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN")) _ = rd.Set("oidc_access_token", os.Getenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN")) - if os.Getenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE") == "" { - diags = append(diags, diag.Diagnostic{ - Severity: diag.Warning, - Summary: "WARNING: The CODER_WORKSPACE_OWNER_LOGIN_TYPE env variable is not set", - }) + if loginType := os.Getenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE"); loginType != "" { + _ = rd.Set("login_type", loginType) } - _ = rd.Set("login_type", os.Getenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE")) return diags }, From 224ff28a6a88e7c3f5c63b554181dd992408e83c Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 11:26:19 +0000 Subject: [PATCH 119/173] ci: allow go version patch upgrades (#313) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5aa16488..76523498 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: '1.22' - name: Import GPG key id: import_gpg From 8b04ef792d81b24d1856f33c692c7b209764427f Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 11:28:10 +0000 Subject: [PATCH 120/173] ci: create draft release (#314) * ci: create draft release * fixup! ci: create draft release --- .github/workflows/release.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 76523498..cab21004 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,3 +46,17 @@ jobs: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} # GitHub sets this automatically GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + ghrelease: + runs-on: ubuntu-latest + needs: ["goreleaser"] + steps: + - name: Create a draft GitHub release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create \ + --draft \ + --title "${GITHUB_REF_NAME}" \ + --notes-from-tag \ + "${GITHUB_REF_NAME}" From 0761ca8b753086f7fb565ec38e8a25e07ed76d87 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 11:56:28 +0000 Subject: [PATCH 121/173] ci: run integration tests before release (#315) --- .github/workflows/release.yml | 52 +++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 20 ++++++++++---- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cab21004..bb023d83 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,58 @@ on: tags: - "v*" jobs: + test: + name: Run Integration Tests + runs-on: ubuntu-latest + steps: + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v4 + + - name: Get dependencies + run: | + go mod download + + - name: Build + env: + CGO_ENABLED: "0" + run: | + go build -v . + + - name: Check Versions + id: checkversions + run: | + source <(go run ./scripts/coderversion) + echo "CODER_MAINLINE_VERSION=${CODER_MAINLINE_VERSION}" >> "${GITHUB_OUTPUT}" + echo "CODER_STABLE_VERSION=${CODER_STABLE_VERSION}" >> "${GITHUB_OUTPUT}" + echo "CODER_OLDSTABLE_VERSION=${CODER_OLDSTABLE_VERSION}" >> "${GITHUB_OUTPUT}" + + - name: Run integration test (mainline) + env: + CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_MAINLINE_VERSION }} + run: | + go test -v ./integration + + - name: Run integration test (stable) + env: + CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_STABLE_VERSION }} + run: | + go test -v ./integration + + - name: Run integration test (oldstable) + env: + CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_OLDSTABLE_VERSION }} + run: | + go test -v ./integration + goreleaser: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eb521f88..69ca7ada 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,6 +38,14 @@ jobs: run: | go build -v . + - name: Check Versions + id: checkversions + run: | + source <(go run ./scripts/coderversion) + echo "CODER_MAINLINE_VERSION=${CODER_MAINLINE_VERSION}" >> "${GITHUB_OUTPUT}" + echo "CODER_STABLE_VERSION=${CODER_STABLE_VERSION}" >> "${GITHUB_OUTPUT}" + echo "CODER_OLDSTABLE_VERSION=${CODER_OLDSTABLE_VERSION}" >> "${GITHUB_OUTPUT}" + - name: Run integration test (devel) timeout-minutes: 10 env: @@ -50,25 +58,25 @@ jobs: timeout-minutes: 10 env: CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_MAINLINE_VERSION }} run: | - source <(go run ./scripts/coderversion) - CODER_VERSION="${CODER_MAINLINE_VERSION}" go test -v ./integration + go test -v ./integration - name: Run integration test (stable) timeout-minutes: 10 env: CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_STABLE_VERSION }} run: | - source <(go run ./scripts/coderversion) - CODER_VERSION="${CODER_STABLE_VERSION}" go test -v ./integration + go test -v ./integration - name: Run integration test (oldstable) timeout-minutes: 10 env: CODER_IMAGE: "ghcr.io/coder/coder" + CODER_VERSION: ${{ steps.checkversions.outputs.CODER_OLDSTABLE_VERSION }} run: | - source <(go run ./scripts/coderversion) - CODER_VERSION="${CODER_OLDSTABLE_VERSION}" go test -v ./integration + go test -v ./integration # run acceptance tests in a matrix with Terraform core versions test: From d15e8d19657b1e4290a18a4da5a1b4fa9ef13971 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Thu, 28 Nov 2024 12:01:32 +0000 Subject: [PATCH 122/173] ci: rm unused action (#316) --- .github/workflows/release.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bb023d83..6bb2f731 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,17 +98,3 @@ jobs: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} # GitHub sets this automatically GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - ghrelease: - runs-on: ubuntu-latest - needs: ["goreleaser"] - steps: - - name: Create a draft GitHub release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release create \ - --draft \ - --title "${GITHUB_REF_NAME}" \ - --notes-from-tag \ - "${GITHUB_REF_NAME}" From 9a97161c34f22ca3fedf8f5b8769931e530e4e37 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 28 Nov 2024 18:03:19 +0500 Subject: [PATCH 123/173] fix(docs): fix formatting issues in upgrade guide for version 2 (#317) --- docs/guides/version-2-upgrade.md | 14 ++++++++------ templates/guides/version-2-upgrade.md.tmpl | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/guides/version-2-upgrade.md b/docs/guides/version-2-upgrade.md index 8c8233eb..9c8063f4 100644 --- a/docs/guides/version-2-upgrade.md +++ b/docs/guides/version-2-upgrade.md @@ -13,8 +13,8 @@ Upgrade topics: - [Provider Version Configuration](#provider-version-configuration) - [Provider Arguments](#provider-arguments) -- [Data Source: [`coder_git_auth`](#data-source-coder_git_auth) -- [Data Source: [`coder_workspace`](#data-source-coder_workspace) +- [Data Source: `coder_git_auth`](#data-source-coder_git_auth) +- [Data Source: `coder_workspace`](#data-source-coder_workspace) ## Provider Version Configuration @@ -60,9 +60,9 @@ provider "coder" {} Version 2.0.0 removes the [`feature_use_managed_variables`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs#feature_use_managed_variables-1) argument from the `provider` block. -## Data Source: [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) +## Data Source: `coder_git_auth` -If you are using this data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. +If you are using the [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. For example, given the previous configuration: @@ -80,14 +80,16 @@ data "coder_external_auth" "example" { } ``` -## Data Source: [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) +## Data Source: `coder_workspace` -If you are using the `owner` properties of the `coder_workspace` data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. +If you are using the `owner` properties of the [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. Update your Terraform configuration to use the `coder_workspace_owner` data source instead and update the following attributes: ```terraform + data "coder_workspace_owner" "me" {} + ``` - Remove `owner_id` attribute. Use [`data.coder_workspace_owner.me.id`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#id) instead. diff --git a/templates/guides/version-2-upgrade.md.tmpl b/templates/guides/version-2-upgrade.md.tmpl index 8c8233eb..9c8063f4 100644 --- a/templates/guides/version-2-upgrade.md.tmpl +++ b/templates/guides/version-2-upgrade.md.tmpl @@ -13,8 +13,8 @@ Upgrade topics: - [Provider Version Configuration](#provider-version-configuration) - [Provider Arguments](#provider-arguments) -- [Data Source: [`coder_git_auth`](#data-source-coder_git_auth) -- [Data Source: [`coder_workspace`](#data-source-coder_workspace) +- [Data Source: `coder_git_auth`](#data-source-coder_git_auth) +- [Data Source: `coder_workspace`](#data-source-coder_workspace) ## Provider Version Configuration @@ -60,9 +60,9 @@ provider "coder" {} Version 2.0.0 removes the [`feature_use_managed_variables`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs#feature_use_managed_variables-1) argument from the `provider` block. -## Data Source: [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) +## Data Source: `coder_git_auth` -If you are using this data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. +If you are using the [`coder_git_auth`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/git_auth) data source, you must replace it with the [`coder_external_auth`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/external_auth) data source. The `coder_external_auth` data source is a more generic data source that can be used to create any external authentication provider which supports OAuth2. For example, given the previous configuration: @@ -80,14 +80,16 @@ data "coder_external_auth" "example" { } ``` -## Data Source: [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) +## Data Source: `coder_workspace` -If you are using the `owner` properties of the `coder_workspace` data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. +If you are using the `owner` properties of the [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/1.0.4/docs/data-sources/workspace) data source, you must remove them and use the [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner) data source instead. The `coder_workspace_owner` data source provides additional properties of the workspace owner. Update your Terraform configuration to use the `coder_workspace_owner` data source instead and update the following attributes: ```terraform + data "coder_workspace_owner" "me" {} + ``` - Remove `owner_id` attribute. Use [`data.coder_workspace_owner.me.id`](https://registry.terraform.io/providers/coder/coder/2.0.0/docs/data-sources/workspace_owner#id) instead. From 2b9f8032198210af11ba50cf64bb8e091c7e5a2c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Fri, 29 Nov 2024 22:00:26 +0500 Subject: [PATCH 124/173] ci: generate release notes automatically (#318) --- .goreleaser.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3866324a..69029533 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -57,4 +57,7 @@ release: # If you want to manually examine the release before its live, uncomment this line: # draft: true changelog: - disable: true + # see https://goreleaser.com/customization/changelog/ + use: github-native + sort: asc + abbrev: 0 From 3d46b7343232c606a18b4ffb0632cebcfb3a5615 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 4 Dec 2024 01:25:46 +0500 Subject: [PATCH 125/173] fix(.goreleaser.yml): use semver to sort git tags (#319) --- .goreleaser.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 69029533..89118d2c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -61,3 +61,5 @@ changelog: use: github-native sort: asc abbrev: 0 +git: + tag_sort: semver From c9dbd6f7639765999b3e84c2f966b3a171d31a4d Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 4 Dec 2024 01:34:11 +0500 Subject: [PATCH 126/173] Revert "fix(.goreleaser.yml): use semver to sort git tags" (#320) --- .goreleaser.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 89118d2c..69029533 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -61,5 +61,3 @@ changelog: use: github-native sort: asc abbrev: 0 -git: - tag_sort: semver From 8349a69f9512f67805f8544c311b4fa8a70dd4f5 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 16 Dec 2024 13:50:06 +0000 Subject: [PATCH 127/173] chore: update golang.org/x/crypto to v0.31.0 (#323) --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 609e1889..9087a1a7 100644 --- a/go.mod +++ b/go.mod @@ -80,11 +80,11 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.28.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index 524564a1..1922dad3 100644 --- a/go.sum +++ b/go.sum @@ -223,8 +223,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -245,8 +245,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -261,8 +261,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -270,8 +270,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From d933a7149b87898dba196342be5dd9df3fc07bcf Mon Sep 17 00:00:00 2001 From: Vincent Vielle Date: Thu, 19 Dec 2024 16:35:25 +0100 Subject: [PATCH 128/173] add open_in option to coder_app (#321) * add open_in option to coder_app * work on tests * add missing example * rename test * lint * generate docs --- docs/resources/app.md | 2 + examples/resources/coder_app/resource.tf | 1 + integration/coder-app-open-in/main.tf | 62 +++++++++++++ integration/integration_test.go | 9 ++ provider/app.go | 22 +++++ provider/app_test.go | 111 +++++++++++++++++++++++ 6 files changed, 207 insertions(+) create mode 100644 integration/coder-app-open-in/main.tf diff --git a/docs/resources/app.md b/docs/resources/app.md index 6b8e99f4..e2bbe435 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -33,6 +33,7 @@ resource "coder_app" "code-server" { url = "http://localhost:13337" share = "owner" subdomain = false + open_in = "window" healthcheck { url = "http://localhost:13337/healthz" interval = 5 @@ -65,6 +66,7 @@ resource "coder_app" "vim" { - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) - `hidden` (Boolean) Determines if the app is visible in the UI (minimum Coder version: v2.16). - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. +- `open_in` (String) Determines where the app will be opened. Valid values are `"tab"`, `"window"`, and `"slim-window" (default)`. `"tab"` opens in a new tab in the same browser window. `"window"` opens a fresh browser window with navigation options. `"slim-window"` opens a new browser window without navigation controls. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). - `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with `subdomain` set to `true` will not be accessible. Defaults to `false`. diff --git a/examples/resources/coder_app/resource.tf b/examples/resources/coder_app/resource.tf index 9345dfc5..8aea7b99 100644 --- a/examples/resources/coder_app/resource.tf +++ b/examples/resources/coder_app/resource.tf @@ -18,6 +18,7 @@ resource "coder_app" "code-server" { url = "http://localhost:13337" share = "owner" subdomain = false + open_in = "window" healthcheck { url = "http://localhost:13337/healthz" interval = 5 diff --git a/integration/coder-app-open-in/main.tf b/integration/coder-app-open-in/main.tf new file mode 100644 index 00000000..529d9bef --- /dev/null +++ b/integration/coder-app-open-in/main.tf @@ -0,0 +1,62 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +data "coder_workspace" "me" {} + +resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + dir = "/workspace" +} + +resource "coder_app" "window" { + agent_id = coder_agent.dev.id + slug = "window" + share = "owner" + open_in = "window" +} + +resource "coder_app" "slim-window" { + agent_id = coder_agent.dev.id + slug = "slim-window" + share = "owner" + open_in = "slim-window" +} + +resource "coder_app" "defaulted" { + agent_id = coder_agent.dev.id + slug = "defaulted" + share = "owner" +} + +locals { + # NOTE: these must all be strings in the output + output = { + "coder_app.window.open_in" = tostring(coder_app.window.open_in) + "coder_app.slim-window.open_in" = tostring(coder_app.slim-window.open_in) + "coder_app.defaulted.open_in" = tostring(coder_app.defaulted.open_in) + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} + diff --git a/integration/integration_test.go b/integration/integration_test.go index f1596eee..50ef71b5 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -143,6 +143,15 @@ func TestIntegration(t *testing.T) { "workspace_owner.login_type": `password`, }, }, + { + name: "coder-app-open-in", + minVersion: "v2.19.0", + expectedOutput: map[string]string{ + "coder_app.window.open_in": "window", + "coder_app.slim-window.open_in": "slim-window", + "coder_app.defaulted.open_in": "slim-window", + }, + }, { name: "coder-app-hidden", minVersion: "v0.0.0", diff --git a/provider/app.go b/provider/app.go index 3fd71692..391bdfc3 100644 --- a/provider/app.go +++ b/provider/app.go @@ -223,6 +223,28 @@ func appResource() *schema.Resource { ForceNew: true, Optional: true, }, + "open_in": { + Type: schema.TypeString, + Description: "Determines where the app will be opened. Valid values are `\"tab\"`, `\"window\"`, and `\"slim-window\" (default)`. " + + "`\"tab\"` opens in a new tab in the same browser window. `\"window\"` opens a fresh browser window with navigation options. " + + "`\"slim-window\"` opens a new browser window without navigation controls.", + ForceNew: true, + Optional: true, + Default: "slim-window", + ValidateDiagFunc: func(val interface{}, c cty.Path) diag.Diagnostics { + valStr, ok := val.(string) + if !ok { + return diag.Errorf("expected string, got %T", val) + } + + switch valStr { + case "tab", "window", "slim-window": + return nil + } + + return diag.Errorf(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": %q`, valStr) + }, + }, }, } } diff --git a/provider/app_test.go b/provider/app_test.go index 6a17ca0c..aaa4f631 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -42,6 +42,7 @@ func TestApp(t *testing.T) { } order = 4 hidden = false + open_in = "slim-window" } `, Check: func(state *terraform.State) error { @@ -64,6 +65,7 @@ func TestApp(t *testing.T) { "healthcheck.0.threshold", "order", "hidden", + "open_in", } { value := resource.Primary.Attributes[key] t.Logf("%q = %q", key, value) @@ -98,6 +100,7 @@ func TestApp(t *testing.T) { display_name = "Testing" url = "https://google.com" external = true + open_in = "slim-window" } `, external: true, @@ -116,6 +119,7 @@ func TestApp(t *testing.T) { url = "https://google.com" external = true subdomain = true + open_in = "slim-window" } `, expectError: regexp.MustCompile("conflicts with subdomain"), @@ -209,6 +213,7 @@ func TestApp(t *testing.T) { interval = 5 threshold = 6 } + open_in = "slim-window" } `, sharingLine) @@ -241,6 +246,106 @@ func TestApp(t *testing.T) { } }) + t.Run("OpenIn", func(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + value string + expectValue string + expectError *regexp.Regexp + }{ + { + name: "default", + value: "", // default + expectValue: "slim-window", + }, + { + name: "InvalidValue", + value: "nonsense", + expectError: regexp.MustCompile(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": "nonsense"`), + }, + { + name: "ExplicitWindow", + value: "window", + expectValue: "window", + }, + { + name: "ExplicitSlimWindow", + value: "slim-window", + expectValue: "slim-window", + }, + { + name: "ExplicitTab", + value: "tab", + expectValue: "tab", + }, + } + + for _, c := range cases { + c := c + + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + config := ` + provider "coder" { + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + } + resource "coder_app" "code-server" { + agent_id = coder_agent.dev.id + slug = "code-server" + display_name = "code-server" + icon = "builtin:vim" + url = "http://localhost:13337" + healthcheck { + url = "http://localhost:13337/healthz" + interval = 5 + threshold = 6 + }` + + if c.value != "" { + config += fmt.Sprintf(` + open_in = %q + `, c.value) + } + + config += ` + } + ` + + checkFn := func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 2) + resource := state.Modules[0].Resources["coder_app.code-server"] + require.NotNil(t, resource) + + // Read share and ensure it matches the expected + // value. + value := resource.Primary.Attributes["open_in"] + require.Equal(t, c.expectValue, value) + return nil + } + if c.expectError != nil { + checkFn = nil + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: config, + Check: checkFn, + ExpectError: c.expectError, + }}, + }) + }) + } + }) + t.Run("Hidden", func(t *testing.T) { t.Parallel() @@ -248,6 +353,7 @@ func TestApp(t *testing.T) { name string config string hidden bool + openIn string }{{ name: "Is Hidden", config: ` @@ -263,9 +369,11 @@ func TestApp(t *testing.T) { url = "https://google.com" external = true hidden = true + open_in = "slim-window" } `, hidden: true, + openIn: "slim-window", }, { name: "Is Not Hidden", config: ` @@ -281,9 +389,11 @@ func TestApp(t *testing.T) { url = "https://google.com" external = true hidden = false + open_in = "window" } `, hidden: false, + openIn: "window", }} for _, tc := range cases { tc := tc @@ -300,6 +410,7 @@ func TestApp(t *testing.T) { resource := state.Modules[0].Resources["coder_app.test"] require.NotNil(t, resource) require.Equal(t, strconv.FormatBool(tc.hidden), resource.Primary.Attributes["hidden"]) + require.Equal(t, tc.openIn, resource.Primary.Attributes["open_in"]) return nil }, ExpectError: nil, From b7ab1bb824ae90b447f6183c671cb0ca5580bb8d Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 20 Dec 2024 13:47:58 +0000 Subject: [PATCH 129/173] chore: update paths to /v2 (#324) --- go.mod | 2 +- main.go | 2 +- provider/agent.go | 2 +- provider/decode_test.go | 2 +- provider/externalauth.go | 2 +- provider/parameter_test.go | 2 +- provider/provider_test.go | 2 +- provider/workspace.go | 2 +- scripts/docsgen/main.go | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 9087a1a7..f88cd289 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/coder/terraform-provider-coder +module github.com/coder/terraform-provider-coder/v2 go 1.22.9 diff --git a/main.go b/main.go index a16c9951..2eaa5dc5 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" - "github.com/coder/terraform-provider-coder/provider" + "github.com/coder/terraform-provider-coder/v2/provider" ) // Run the docs generation tool, check its repository for more information on how it works and how docs diff --git a/provider/agent.go b/provider/agent.go index 01fb5801..ac012bf1 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "golang.org/x/xerrors" - "github.com/coder/terraform-provider-coder/provider/helpers" + "github.com/coder/terraform-provider-coder/v2/provider/helpers" ) func agentResource() *schema.Resource { diff --git a/provider/decode_test.go b/provider/decode_test.go index a5e20b14..947ebf79 100644 --- a/provider/decode_test.go +++ b/provider/decode_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/coder/terraform-provider-coder/provider" + "github.com/coder/terraform-provider-coder/v2/provider" ) func TestDecode(t *testing.T) { diff --git a/provider/externalauth.go b/provider/externalauth.go index a11a67c4..915a21a9 100644 --- a/provider/externalauth.go +++ b/provider/externalauth.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/coder/terraform-provider-coder/provider/helpers" + "github.com/coder/terraform-provider-coder/v2/provider/helpers" ) // externalAuthDataSource returns a schema for an external authentication data source. diff --git a/provider/parameter_test.go b/provider/parameter_test.go index fc814cba..b1f164a0 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" - "github.com/coder/terraform-provider-coder/provider" + "github.com/coder/terraform-provider-coder/v2/provider" ) func TestParameter(t *testing.T) { diff --git a/provider/provider_test.go b/provider/provider_test.go index 3367e7f4..4bf98b32 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/require" - "github.com/coder/terraform-provider-coder/provider" + "github.com/coder/terraform-provider-coder/v2/provider" ) func TestProvider(t *testing.T) { diff --git a/provider/workspace.go b/provider/workspace.go index 575fd60f..fde742b6 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/coder/terraform-provider-coder/provider/helpers" + "github.com/coder/terraform-provider-coder/v2/provider/helpers" ) func workspaceDataSource() *schema.Resource { diff --git a/scripts/docsgen/main.go b/scripts/docsgen/main.go index d83cf123..53b43ca4 100644 --- a/scripts/docsgen/main.go +++ b/scripts/docsgen/main.go @@ -9,7 +9,7 @@ import ( "regexp" "strings" - "github.com/coder/terraform-provider-coder/provider" + "github.com/coder/terraform-provider-coder/v2/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "golang.org/x/xerrors" ) From 464d613873cab9b1424c0c5a4d5c74ae3bf52927 Mon Sep 17 00:00:00 2001 From: Vincent Vielle Date: Mon, 20 Jan 2025 13:59:24 +0100 Subject: [PATCH 130/173] fix: remove window option from open_in parameter (#327) * remove window option * fix missing integration test * fix tests * run linter --- docs/resources/app.md | 2 +- integration/coder-app-open-in/main.tf | 18 +++++------------- integration/integration_test.go | 5 ++--- provider/app.go | 8 ++++---- provider/app_test.go | 11 +++-------- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/docs/resources/app.md b/docs/resources/app.md index e2bbe435..b3ac728f 100644 --- a/docs/resources/app.md +++ b/docs/resources/app.md @@ -66,7 +66,7 @@ resource "coder_app" "vim" { - `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck)) - `hidden` (Boolean) Determines if the app is visible in the UI (minimum Coder version: v2.16). - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. -- `open_in` (String) Determines where the app will be opened. Valid values are `"tab"`, `"window"`, and `"slim-window" (default)`. `"tab"` opens in a new tab in the same browser window. `"window"` opens a fresh browser window with navigation options. `"slim-window"` opens a new browser window without navigation controls. +- `open_in` (String) Determines where the app will be opened. Valid values are `"tab"` and `"slim-window" (default)`. `"tab"` opens in a new tab in the same browser window. `"slim-window"` opens a new browser window without navigation controls. - `order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order). - `share` (String) Determines the level which the application is shared at. Valid levels are `"owner"` (default), `"authenticated"` and `"public"`. Level `"owner"` disables sharing on the app, so only the workspace owner can access it. Level `"authenticated"` shares the app with all authenticated users. Level `"public"` shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only). - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with `subdomain` set to `true` will not be accessible. Defaults to `false`. diff --git a/integration/coder-app-open-in/main.tf b/integration/coder-app-open-in/main.tf index 529d9bef..f06947ae 100644 --- a/integration/coder-app-open-in/main.tf +++ b/integration/coder-app-open-in/main.tf @@ -17,18 +17,11 @@ resource "coder_agent" "dev" { dir = "/workspace" } -resource "coder_app" "window" { +resource "coder_app" "tab" { agent_id = coder_agent.dev.id - slug = "window" + slug = "tab" share = "owner" - open_in = "window" -} - -resource "coder_app" "slim-window" { - agent_id = coder_agent.dev.id - slug = "slim-window" - share = "owner" - open_in = "slim-window" + open_in = "tab" } resource "coder_app" "defaulted" { @@ -40,9 +33,8 @@ resource "coder_app" "defaulted" { locals { # NOTE: these must all be strings in the output output = { - "coder_app.window.open_in" = tostring(coder_app.window.open_in) - "coder_app.slim-window.open_in" = tostring(coder_app.slim-window.open_in) - "coder_app.defaulted.open_in" = tostring(coder_app.defaulted.open_in) + "coder_app.tab.open_in" = tostring(coder_app.tab.open_in) + "coder_app.defaulted.open_in" = tostring(coder_app.defaulted.open_in) } } diff --git a/integration/integration_test.go b/integration/integration_test.go index 50ef71b5..8ac68f28 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -147,9 +147,8 @@ func TestIntegration(t *testing.T) { name: "coder-app-open-in", minVersion: "v2.19.0", expectedOutput: map[string]string{ - "coder_app.window.open_in": "window", - "coder_app.slim-window.open_in": "slim-window", - "coder_app.defaulted.open_in": "slim-window", + "coder_app.tab.open_in": "tab", + "coder_app.defaulted.open_in": "slim-window", }, }, { diff --git a/provider/app.go b/provider/app.go index 391bdfc3..cd64db54 100644 --- a/provider/app.go +++ b/provider/app.go @@ -225,8 +225,8 @@ func appResource() *schema.Resource { }, "open_in": { Type: schema.TypeString, - Description: "Determines where the app will be opened. Valid values are `\"tab\"`, `\"window\"`, and `\"slim-window\" (default)`. " + - "`\"tab\"` opens in a new tab in the same browser window. `\"window\"` opens a fresh browser window with navigation options. " + + Description: "Determines where the app will be opened. Valid values are `\"tab\"` and `\"slim-window\" (default)`. " + + "`\"tab\"` opens in a new tab in the same browser window. " + "`\"slim-window\"` opens a new browser window without navigation controls.", ForceNew: true, Optional: true, @@ -238,11 +238,11 @@ func appResource() *schema.Resource { } switch valStr { - case "tab", "window", "slim-window": + case "tab", "slim-window": return nil } - return diag.Errorf(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": %q`, valStr) + return diag.Errorf(`invalid "coder_app" open_in value, must be one of "tab", "slim-window": %q`, valStr) }, }, }, diff --git a/provider/app_test.go b/provider/app_test.go index aaa4f631..005e8377 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -263,12 +263,7 @@ func TestApp(t *testing.T) { { name: "InvalidValue", value: "nonsense", - expectError: regexp.MustCompile(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": "nonsense"`), - }, - { - name: "ExplicitWindow", - value: "window", - expectValue: "window", + expectError: regexp.MustCompile(`invalid "coder_app" open_in value, must be one of "tab", "slim-window": "nonsense"`), }, { name: "ExplicitSlimWindow", @@ -389,11 +384,11 @@ func TestApp(t *testing.T) { url = "https://google.com" external = true hidden = false - open_in = "window" + open_in = "tab" } `, hidden: false, - openIn: "window", + openIn: "tab", }} for _, tc := range cases { tc := tc From 3c23e37fe329803dcb5763acc035402bc1dd8d34 Mon Sep 17 00:00:00 2001 From: Vincent Vielle Date: Wed, 22 Jan 2025 14:19:14 +0100 Subject: [PATCH 131/173] doc: add release section (#328) * update readme release section * Update README.md Co-authored-by: Muhammad Atif Ali --------- Co-authored-by: Muhammad Atif Ali --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 6f13efef..cf012c46 100644 --- a/README.md +++ b/README.md @@ -77,3 +77,18 @@ To run these integration tests locally: > **Note:** you can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. > For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`. + +### How to create a new release +> **Warning:** Before creating a new release, make sure you have pulled the latest commit from the main branch i.e. `git pull origin main` + +1. Create a new tag with a version number (following semantic versioning): + ```console + git tag -a v2.1.2 -m "v2.1.2" + ``` + +2. Push the tag to the remote repository: + ```console + git push origin tag v2.1.2 + ``` + +A GitHub Actions workflow named "Release" will automatically trigger, run integration tests, and publish the new release. \ No newline at end of file From 054e9bca452d7715f169c48d1c169314151118e2 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 22 Jan 2025 23:38:54 +0500 Subject: [PATCH 132/173] chore: Prettify README.md (#329) --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf012c46..b8ee8840 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ to setup your local Terraform to use your local version rather than the registry To run Terraform acceptance tests, run `make testacc`. This will test the provider against the locally installed version of Terraform. -> **Note:** our [CI workflow](./github/workflows/test.yml) runs a test matrix against multiple Terraform versions. +> [!Note] +> Our [CI workflow](./github/workflows/test.yml) runs a test matrix against multiple Terraform versions. #### Integration Tests @@ -75,11 +76,13 @@ To run these integration tests locally: 1. Run `CODER_IMAGE=ghcr.io/coder/coder-preview CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. -> **Note:** you can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. +> [!Note] +> You can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. > For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`. ### How to create a new release -> **Warning:** Before creating a new release, make sure you have pulled the latest commit from the main branch i.e. `git pull origin main` +> [!Warning] +> Before creating a new release, make sure you have pulled the latest commit from the main branch i.e. `git pull origin main` 1. Create a new tag with a version number (following semantic versioning): ```console @@ -91,4 +94,4 @@ To run these integration tests locally: git push origin tag v2.1.2 ``` -A GitHub Actions workflow named "Release" will automatically trigger, run integration tests, and publish the new release. \ No newline at end of file +A GitHub Actions workflow named "Release" will automatically trigger, run integration tests, and publish the new release. From d7d2b705fc00673bfd1a4f55efe97dfa7f89da84 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Tue, 4 Feb 2025 10:26:06 +0200 Subject: [PATCH 133/173] feat: add a workspace preset datasource (#332) * add a workspace preset datasource * add workspace preset type * add validation and tests for coder_workspace_presets * make -B gen * make -B gen * idiomatic tests and review notes * make fmt * make -B gen * add integration tests * make gen fmt --- docs/data-sources/workspace_preset.md | 42 ++++++ .../coder_workspace_preset/data-source.tf | 14 ++ integration/integration_test.go | 45 ++++-- integration/test-data-source/main.tf | 17 +++ integration/test-data-source/parameters.yaml | 1 + provider/provider.go | 13 +- provider/workspace_preset.go | 70 ++++++++++ provider/workspace_preset_test.go | 128 ++++++++++++++++++ 8 files changed, 311 insertions(+), 19 deletions(-) create mode 100644 docs/data-sources/workspace_preset.md create mode 100644 examples/data-sources/coder_workspace_preset/data-source.tf create mode 100644 integration/test-data-source/parameters.yaml create mode 100644 provider/workspace_preset.go create mode 100644 provider/workspace_preset_test.go diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md new file mode 100644 index 00000000..28f90faa --- /dev/null +++ b/docs/data-sources/workspace_preset.md @@ -0,0 +1,42 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_workspace_preset Data Source - terraform-provider-coder" +subcategory: "" +description: |- + Use this data source to predefine common configurations for workspaces. +--- + +# coder_workspace_preset (Data Source) + +Use this data source to predefine common configurations for workspaces. + +## Example Usage + +```terraform +provider "coder" {} + +# presets can be used to predefine common configurations for workspaces +# Parameters are referenced by their name. Each parameter must be defined in the preset. +# Values defined by the preset must pass validation for the parameter. +# See the coder_parameter data source's documentation for examples of how to define +# parameters like the ones used below. +data "coder_workspace_preset" "example" { + name = "example" + parameters = { + (data.coder_parameter.example.name) = "us-central1-a" + (data.coder_parameter.ami.name) = "ami-xxxxxxxx" + } +} +``` + + +## Schema + +### Required + +- `name` (String) Name of the workspace preset. +- `parameters` (Map of String) Parameters of the workspace preset. + +### Read-Only + +- `id` (String) ID of the workspace preset. diff --git a/examples/data-sources/coder_workspace_preset/data-source.tf b/examples/data-sources/coder_workspace_preset/data-source.tf new file mode 100644 index 00000000..4f29a199 --- /dev/null +++ b/examples/data-sources/coder_workspace_preset/data-source.tf @@ -0,0 +1,14 @@ +provider "coder" {} + +# presets can be used to predefine common configurations for workspaces +# Parameters are referenced by their name. Each parameter must be defined in the preset. +# Values defined by the preset must pass validation for the parameter. +# See the coder_parameter data source's documentation for examples of how to define +# parameters like the ones used below. +data "coder_workspace_preset" "example" { + name = "example" + parameters = { + (data.coder_parameter.example.name) = "us-central1-a" + (data.coder_parameter.ami.name) = "ami-xxxxxxxx" + } +} diff --git a/integration/integration_test.go b/integration/integration_test.go index 8ac68f28..bbbd5587 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -73,18 +73,27 @@ func TestIntegration(t *testing.T) { name: "test-data-source", minVersion: "v0.0.0", expectedOutput: map[string]string{ - "provisioner.arch": runtime.GOARCH, - "provisioner.id": `[a-zA-Z0-9-]+`, - "provisioner.os": runtime.GOOS, - "workspace.access_port": `\d+`, - "workspace.access_url": `https?://\D+:\d+`, - "workspace.id": `[a-zA-z0-9-]+`, - "workspace.name": `test-data-source`, - "workspace.start_count": `1`, - "workspace.template_id": `[a-zA-Z0-9-]+`, - "workspace.template_name": `test-data-source`, - "workspace.template_version": `.+`, - "workspace.transition": `start`, + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": `test-data-source`, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `test-data-source`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, + "workspace_parameter.name": `param`, + "workspace_parameter.description": `param description`, + // TODO (sasswart): the cli doesn't support presets yet. + // once it does, the value for workspace_parameter.value + // will be the preset value. + "workspace_parameter.value": `param value`, + "workspace_parameter.icon": `param icon`, + "workspace_preset.name": `preset`, + "workspace_preset.parameters.param": `preset param value`, }, }, { @@ -179,8 +188,18 @@ func TestIntegration(t *testing.T) { } _, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`coder templates %s %s --directory /src/integration/%s --var output_path=/tmp/%s.json --yes`, templateCreateCmd, tt.name, tt.name, tt.name)) require.Equal(t, 0, rc) + + // Check if parameters.yaml exists + _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`stat /src/integration/%s/parameters.yaml 2>/dev/null > /dev/null`, tt.name)) + hasParameters := rc == 0 + var includeParameters string + if hasParameters { + // If it exists, include it in the create command + includeParameters = fmt.Sprintf(`--rich-parameter-file /src/integration/%s/parameters.yaml`, tt.name) + } + // Create a workspace - _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s --yes`, tt.name, tt.name)) + _, rc = execContainer(ctx, t, ctrID, fmt.Sprintf(`coder create %s -t %s %s --yes`, tt.name, tt.name, includeParameters)) require.Equal(t, 0, rc) // Fetch the output created by the template out, rc := execContainer(ctx, t, ctrID, fmt.Sprintf(`cat /tmp/%s.json`, tt.name)) diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 6d4b85cd..5fb2e0e6 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -14,6 +14,17 @@ terraform { data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} +data "coder_parameter" "param" { + name = "param" + description = "param description" + icon = "param icon" +} +data "coder_workspace_preset" "preset" { + name = "preset" + parameters = { + (data.coder_parameter.param.name) = "preset param value" + } +} locals { # NOTE: these must all be strings in the output @@ -30,6 +41,12 @@ locals { "workspace.template_name" : data.coder_workspace.me.template_name, "workspace.template_version" : data.coder_workspace.me.template_version, "workspace.transition" : data.coder_workspace.me.transition, + "workspace_parameter.name" : data.coder_parameter.param.name, + "workspace_parameter.description" : data.coder_parameter.param.description, + "workspace_parameter.value" : data.coder_parameter.param.value, + "workspace_parameter.icon" : data.coder_parameter.param.icon, + "workspace_preset.name" : data.coder_workspace_preset.preset.name, + "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, } } diff --git a/integration/test-data-source/parameters.yaml b/integration/test-data-source/parameters.yaml new file mode 100644 index 00000000..0e75c133 --- /dev/null +++ b/integration/test-data-source/parameters.yaml @@ -0,0 +1 @@ +param: "param value" \ No newline at end of file diff --git a/provider/provider.go b/provider/provider.go index 1d78f2dd..d9780d76 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -61,12 +61,13 @@ func New() *schema.Provider { }, nil }, DataSourcesMap: map[string]*schema.Resource{ - "coder_workspace": workspaceDataSource(), - "coder_workspace_tags": workspaceTagDataSource(), - "coder_provisioner": provisionerDataSource(), - "coder_parameter": parameterDataSource(), - "coder_external_auth": externalAuthDataSource(), - "coder_workspace_owner": workspaceOwnerDataSource(), + "coder_workspace": workspaceDataSource(), + "coder_workspace_tags": workspaceTagDataSource(), + "coder_provisioner": provisionerDataSource(), + "coder_parameter": parameterDataSource(), + "coder_external_auth": externalAuthDataSource(), + "coder_workspace_owner": workspaceOwnerDataSource(), + "coder_workspace_preset": workspacePresetDataSource(), }, ResourcesMap: map[string]*schema.Resource{ "coder_agent": agentResource(), diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go new file mode 100644 index 00000000..cd56c980 --- /dev/null +++ b/provider/workspace_preset.go @@ -0,0 +1,70 @@ +package provider + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/mitchellh/mapstructure" +) + +type WorkspacePreset struct { + Name string `mapstructure:"name"` + Parameters map[string]string `mapstructure:"parameters"` +} + +func workspacePresetDataSource() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Description: "Use this data source to predefine common configurations for workspaces.", + ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { + var preset WorkspacePreset + err := mapstructure.Decode(struct { + Name interface{} + Parameters interface{} + }{ + Name: rd.Get("name"), + Parameters: rd.Get("parameters"), + }, &preset) + if err != nil { + return diag.Errorf("decode workspace preset: %s", err) + } + + // MinItems doesn't work with maps, so we need to check the length + // of the map manually. All other validation is handled by the + // schema. + if len(preset.Parameters) == 0 { + return diag.Errorf("expected \"parameters\" to not be an empty map") + } + + rd.SetId(preset.Name) + + return nil + }, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "ID of the workspace preset.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Name of the workspace preset.", + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "parameters": { + Type: schema.TypeMap, + Description: "Parameters of the workspace preset.", + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, + } +} diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go new file mode 100644 index 00000000..876e2044 --- /dev/null +++ b/provider/workspace_preset_test.go @@ -0,0 +1,128 @@ +package provider_test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/require" +) + +func TestWorkspacePreset(t *testing.T) { + t.Parallel() + type testcase struct { + Name string + Config string + ExpectError *regexp.Regexp + Check func(state *terraform.State) error + } + testcases := []testcase{ + { + Name: "Happy Path", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + }`, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_workspace_preset.preset_1"] + require.NotNil(t, resource) + attrs := resource.Primary.Attributes + require.Equal(t, attrs["name"], "preset_1") + require.Equal(t, attrs["parameters.region"], "us-east1-a") + return nil + }, + }, + { + Name: "Name field is not provided", + Config: ` + data "coder_workspace_preset" "preset_1" { + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("The argument \"name\" is required, but no definition was found"), + }, + { + Name: "Name field is empty", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "" + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("expected \"name\" to not be an empty string"), + }, + { + Name: "Name field is not a string", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = [1, 2, 3] + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("Incorrect attribute value type"), + }, + { + Name: "Parameters field is not provided", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("The argument \"parameters\" is required, but no definition was found"), + }, + { + Name: "Parameters field is empty", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = {} + }`, + // This validation is *not* done by Terraform, because MinItems doesn't work with maps. + // We've implemented the validation in ReadContext, so we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("expected \"parameters\" to not be an empty map"), + }, + { + Name: "Parameters field is not a map", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = "not a map" + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("Inappropriate value for attribute \"parameters\": map of string required"), + }, + } + + for _, testcase := range testcases { + t.Run(testcase.Name, func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: testcase.Config, + ExpectError: testcase.ExpectError, + Check: testcase.Check, + }}, + }) + }) + } +} From b73223c16edef7c407eacbded79e8a0b99a8f0a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:24:29 +0000 Subject: [PATCH 134/173] build(deps): Bump golang.org/x/mod from 0.22.0 to 0.23.0 (#337) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.22.0 to 0.23.0. - [Commits](https://github.com/golang/mod/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f88cd289..f4f8d4b0 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/mod v0.22.0 + golang.org/x/mod v0.23.0 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index 1922dad3..ab31763e 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXy 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= From ec48bcb742656c13ec21fd3b2be15b1138565425 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:25:06 +0000 Subject: [PATCH 135/173] build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 (#338) Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.35.0 to 2.36.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.35.0...v2.36.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 37 +++++++++++------------ go.sum | 94 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/go.mod b/go.mod index f4f8d4b0..c1033b5e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 @@ -19,7 +19,7 @@ require ( require ( github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect @@ -30,7 +30,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -44,14 +44,14 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/hc-install v0.9.0 // indirect - github.com/hashicorp/hcl/v2 v2.22.0 // indirect + github.com/hashicorp/hc-install v0.9.1 // indirect + github.com/hashicorp/hcl/v2 v2.23.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.21.0 // indirect - github.com/hashicorp/terraform-json v0.23.0 // indirect - github.com/hashicorp/terraform-plugin-go v0.25.0 // indirect + github.com/hashicorp/terraform-exec v0.22.0 // indirect + github.com/hashicorp/terraform-json v0.24.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.3 // indirect + github.com/hashicorp/terraform-registry-address v0.2.4 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/kr/pretty v0.3.0 // indirect @@ -73,24 +73,23 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.15.0 // indirect + github.com/zclconf/go-cty v1.16.2 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.28.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + google.golang.org/grpc v1.69.4 // indirect + google.golang.org/protobuf v1.36.3 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index ab31763e..a8819092 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= @@ -22,8 +22,8 @@ github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBS github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,13 +44,13 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-git/v5 v5.13.0 h1:vLn5wlGIh/X78El6r3Jr+30W16Blk0CTcxTYcYPWi5E= +github.com/go-git/go-git/v5 v5.13.0/go.mod h1:Wjo7/JyVKtQgUNdXYXIepzWfJQkUEIGvkvVkiXRR/zw= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= @@ -95,24 +95,24 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= -github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= -github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= -github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/hc-install v0.9.1 h1:gkqTfE3vVbafGQo6VZXcy2v5yoz2bE0+nhZXruCuODQ= +github.com/hashicorp/hc-install v0.9.1/go.mod h1:pWWvN/IrfeBK4XPeXXYkL6EjMufHkCK5DvwxeLKuBf0= +github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= +github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= -github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= -github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= -github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= -github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= +github.com/hashicorp/terraform-exec v0.22.0 h1:G5+4Sz6jYZfRYUCg6eQgDsqTzkNXV+fP8l+uRmZHj64= +github.com/hashicorp/terraform-exec v0.22.0/go.mod h1:bjVbsncaeh8jVdhttWYZuBGj21FcYw6Ia/XfHcNO7lQ= +github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q= +github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow= +github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M= +github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= -github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= -github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 h1:7/iejAPyCRBhqAg3jOx+4UcAhY0A+Sg8B+0+d/GxSfM= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0/go.mod h1:TiQwXAjFrgBf5tg5rvBRz8/ubPULpU0HjSaVi5UoJf8= +github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA= +github.com/hashicorp/terraform-registry-address v0.2.4/go.mod h1:tUNYTVyCtU4OIGXXMDp7WNcJ+0W1B4nmstVDgHMjfAU= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= @@ -181,8 +181,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -199,32 +199,34 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI 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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= -github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70= +github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= -go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -238,8 +240,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL 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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= @@ -261,8 +263,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -291,12 +293,12 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= +google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 5e4c5966ba27873ec498ba83139d0cfde142899f Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Fri, 7 Feb 2025 15:49:10 +0500 Subject: [PATCH 136/173] fix(docs): fix parameter options icons (#339) --- docs/data-sources/parameter.md | 10 +++++----- examples/data-sources/coder_parameter/data-source.tf | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index f40a9c83..4da9dac2 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -20,16 +20,16 @@ data "coder_parameter" "example" { description = "Specify a region to place your workspace." mutable = false type = "string" - default = "asia-central1-a" + default = "us-central1-a" option { value = "us-central1-a" name = "US Central" - icon = "/icon/usa.svg" + icon = "/icons/1f1fa-1f1f8.png" } option { - value = "asia-central1-a" - name = "Asia" - icon = "/icon/asia.svg" + value = "asia-southeast1-a" + name = "Singapore" + icon = "/icons/1f1f8-1f1ec.png" } } diff --git a/examples/data-sources/coder_parameter/data-source.tf b/examples/data-sources/coder_parameter/data-source.tf index 4efc3320..ac0de7cb 100644 --- a/examples/data-sources/coder_parameter/data-source.tf +++ b/examples/data-sources/coder_parameter/data-source.tf @@ -5,16 +5,16 @@ data "coder_parameter" "example" { description = "Specify a region to place your workspace." mutable = false type = "string" - default = "asia-central1-a" + default = "us-central1-a" option { value = "us-central1-a" name = "US Central" - icon = "/icon/usa.svg" + icon = "/icons/1f1fa-1f1f8.png" } option { - value = "asia-central1-a" - name = "Asia" - icon = "/icon/asia.svg" + value = "asia-southeast1-a" + name = "Singapore" + icon = "/icons/1f1f8-1f1ec.png" } } From c9b396f1997db20188ce674dd6335e8b6ac7b6f3 Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Fri, 7 Feb 2025 15:54:08 +0500 Subject: [PATCH 137/173] ci: drop support for EOL terraform version (#340) --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69ca7ada..88ccde05 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,11 +88,8 @@ jobs: fail-fast: false matrix: terraform: - - "1.5.*" - - "1.6.*" - - "1.7.*" - - "1.8.*" - "1.9.*" + - "1.10.*" steps: - name: Set up Go uses: actions/setup-go@v5 From 1f958079cf6996d72fbdd1d8b0ecff0815b4680f Mon Sep 17 00:00:00 2001 From: Vincent Vielle Date: Fri, 7 Feb 2025 14:58:34 +0100 Subject: [PATCH 138/173] feat: add resources_monitoring field to agent (#331) * add resources_monitoring logic * add resources_monitoring logic * improve testing logic * improve testing logic * gen doc * improved testing and validation * improved testing and validation * improved testing and validation * regenerate documentation with validation * add more test cases * add validation methods * improve test verbose --- docs/resources/agent.md | 28 ++ .../coder_resources_monitoring/data-source.tf | 26 ++ provider/agent.go | 143 ++++++++- provider/agent_test.go | 296 ++++++++++++++++++ provider/examples_test.go | 1 + 5 files changed, 479 insertions(+), 15 deletions(-) create mode 100644 examples/data-sources/coder_resources_monitoring/data-source.tf diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 8c786d6e..7c28b1f4 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -79,6 +79,7 @@ resource "kubernetes_pod" "dev" { - `metadata` (Block List) Each `metadata` block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be `"/etc/motd"`. - `order` (Number) The order determines the position of agents in the UI presentation. The lowest order is shown first and agents with equal order are sorted by name (ascending order). +- `resources_monitoring` (Block Set, Max: 1) The resources monitoring configuration for this agent. (see [below for nested schema](#nestedblock--resources_monitoring)) - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. This option is an alias for defining a `coder_script` resource with `run_on_stop` set to `true`. - `startup_script` (String) A script to run after the agent starts. The script should exit when it is done to signal that the agent is ready. This option is an alias for defining a `coder_script` resource with `run_on_start` set to `true`. - `startup_script_behavior` (String) This option sets the behavior of the `startup_script`. When set to `"blocking"`, the `startup_script` must exit before the workspace is ready. When set to `"non-blocking"`, the `startup_script` may run in the background and the workspace will be ready immediately. Default is `"non-blocking"`, although `"blocking"` is recommended. This option is an alias for defining a `coder_script` resource with `start_blocks_login` set to `true` (blocking). @@ -116,3 +117,30 @@ Optional: - `display_name` (String) The user-facing name of this value. - `order` (Number) The order determines the position of agent metadata in the UI presentation. The lowest order is shown first and metadata with equal order are sorted by key (ascending order). - `timeout` (Number) The maximum time the command is allowed to run in seconds. + + + +### Nested Schema for `resources_monitoring` + +Optional: + +- `memory` (Block Set, Max: 1) The memory monitoring configuration for this agent. (see [below for nested schema](#nestedblock--resources_monitoring--memory)) +- `volume` (Block Set) The volumes monitoring configuration for this agent. (see [below for nested schema](#nestedblock--resources_monitoring--volume)) + + +### Nested Schema for `resources_monitoring.memory` + +Required: + +- `enabled` (Boolean) Enable memory monitoring for this agent. +- `threshold` (Number) The memory usage threshold in percentage at which to trigger an alert. Value should be between 0 and 100. + + + +### Nested Schema for `resources_monitoring.volume` + +Required: + +- `enabled` (Boolean) Enable volume monitoring for this agent. +- `path` (String) The path of the volume to monitor. +- `threshold` (Number) The volume usage threshold in percentage at which to trigger an alert. Value should be between 0 and 100. diff --git a/examples/data-sources/coder_resources_monitoring/data-source.tf b/examples/data-sources/coder_resources_monitoring/data-source.tf new file mode 100644 index 00000000..94bc55ed --- /dev/null +++ b/examples/data-sources/coder_resources_monitoring/data-source.tf @@ -0,0 +1,26 @@ +provider "coder" {} + +data "coder_provisioner" "dev" {} + +data "coder_workspace" "dev" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.dev.arch + os = data.coder_provisioner.dev.os + resources_monitoring { + memory { + enabled = true + threshold = 80 + } + volume { + path = "/volume1" + enabled = true + threshold = 80 + } + volume { + path = "/volume2" + enabled = true + threshold = 100 + } + } +} \ No newline at end of file diff --git a/provider/agent.go b/provider/agent.go index ac012bf1..3ddae235 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -3,10 +3,12 @@ package provider import ( "context" "fmt" + "path/filepath" "reflect" "strings" "github.com/google/uuid" + "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -259,31 +261,142 @@ func agentResource() *schema.Resource { ForceNew: true, Optional: true, }, + "resources_monitoring": { + Type: schema.TypeSet, + Description: "The resources monitoring configuration for this agent.", + ForceNew: true, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "memory": { + Type: schema.TypeSet, + Description: "The memory monitoring configuration for this agent.", + ForceNew: true, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Description: "Enable memory monitoring for this agent.", + ForceNew: true, + Required: true, + }, + "threshold": { + Type: schema.TypeInt, + Description: "The memory usage threshold in percentage at which to trigger an alert. Value should be between 0 and 100.", + ForceNew: true, + Required: true, + ValidateFunc: validation.IntBetween(0, 100), + }, + }, + }, + }, + "volume": { + Type: schema.TypeSet, + Description: "The volumes monitoring configuration for this agent.", + ForceNew: true, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Description: "The path of the volume to monitor.", + ForceNew: true, + Required: true, + ValidateDiagFunc: func(i interface{}, s cty.Path) diag.Diagnostics { + path, ok := i.(string) + if !ok { + return diag.Errorf("volume path must be a string") + } + if path == "" { + return diag.Errorf("volume path must not be empty") + } + + if !filepath.IsAbs(i.(string)) { + return diag.Errorf("volume path must be an absolute path") + } + + return nil + }, + }, + "enabled": { + Type: schema.TypeBool, + Description: "Enable volume monitoring for this agent.", + ForceNew: true, + Required: true, + }, + "threshold": { + Type: schema.TypeInt, + Description: "The volume usage threshold in percentage at which to trigger an alert. Value should be between 0 and 100.", + ForceNew: true, + Required: true, + ValidateFunc: validation.IntBetween(0, 100), + }, + }, + }, + }, + }, + }, + }, }, CustomizeDiff: func(ctx context.Context, rd *schema.ResourceDiff, i any) error { - if !rd.HasChange("metadata") { - return nil + if rd.HasChange("metadata") { + keys := map[string]bool{} + metadata, ok := rd.Get("metadata").([]any) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata, expected []any", rd.Get("metadata")) + } + for _, t := range metadata { + obj, ok := t.(map[string]any) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata, expected map[string]any", t) + } + key, ok := obj["key"].(string) + if !ok { + return xerrors.Errorf("unexpected type %T for metadata key, expected string", obj["key"]) + } + if keys[key] { + return xerrors.Errorf("duplicate agent metadata key %q", key) + } + keys[key] = true + } } - keys := map[string]bool{} - metadata, ok := rd.Get("metadata").([]any) - if !ok { - return xerrors.Errorf("unexpected type %T for metadata, expected []any", rd.Get("metadata")) - } - for _, t := range metadata { - obj, ok := t.(map[string]any) + if rd.HasChange("resources_monitoring") { + monitors, ok := rd.Get("resources_monitoring").(*schema.Set) if !ok { - return xerrors.Errorf("unexpected type %T for metadata, expected map[string]any", t) + return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", rd.Get("resources_monitoring.0.volume")) } - key, ok := obj["key"].(string) + + monitor := monitors.List()[0].(map[string]any) + + volumes, ok := monitor["volume"].(*schema.Set) if !ok { - return xerrors.Errorf("unexpected type %T for metadata key, expected string", obj["key"]) + return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", monitor["volume"]) } - if keys[key] { - return xerrors.Errorf("duplicate agent metadata key %q", key) + + paths := map[string]bool{} + for _, volume := range volumes.List() { + obj, ok := volume.(map[string]any) + if !ok { + return xerrors.Errorf("unexpected type %T for volume, expected map[string]any", volume) + } + + // print path for debug purpose + + path, ok := obj["path"].(string) + if !ok { + return xerrors.Errorf("unexpected type %T for volume path, expected string", obj["path"]) + } + if paths[path] { + return xerrors.Errorf("duplicate volume path %q", path) + } + paths[path] = true } - keys[key] = true } + return nil }, } diff --git a/provider/agent_test.go b/provider/agent_test.go index d40caf56..a45ac86a 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -211,6 +211,302 @@ func TestAgent_Metadata(t *testing.T) { }) } +func TestAgent_ResourcesMonitoring(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + memory { + enabled = true + threshold = 80 + } + volume { + path = "/volume1" + enabled = true + threshold = 80 + } + volume { + path = "/volume2" + enabled = true + threshold = 100 + } + } + }`, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + attr := resource.Primary.Attributes + require.Equal(t, "1", attr["resources_monitoring.#"]) + require.Equal(t, "1", attr["resources_monitoring.0.memory.#"]) + require.Equal(t, "2", attr["resources_monitoring.0.volume.#"]) + require.Equal(t, "80", attr["resources_monitoring.0.memory.0.threshold"]) + require.Equal(t, "/volume1", attr["resources_monitoring.0.volume.0.path"]) + require.Equal(t, "100", attr["resources_monitoring.0.volume.1.threshold"]) + require.Equal(t, "/volume2", attr["resources_monitoring.0.volume.1.path"]) + return nil + }, + }}, + }) + }) + + t.Run("OnlyMemory", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + memory { + enabled = true + threshold = 80 + } + } + }`, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + attr := resource.Primary.Attributes + require.Equal(t, "1", attr["resources_monitoring.#"]) + require.Equal(t, "1", attr["resources_monitoring.0.memory.#"]) + require.Equal(t, "80", attr["resources_monitoring.0.memory.0.threshold"]) + return nil + }, + }}, + }) + }) + t.Run("MultipleMemory", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + memory { + enabled = true + threshold = 80 + } + memory { + enabled = true + threshold = 90 + } + } + }`, + ExpectError: regexp.MustCompile(`No more than 1 "memory" blocks are allowed`), + }}, + }) + }) + + t.Run("InvalidThreshold", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + memory { + enabled = true + threshold = 101 + } + } + }`, + Check: nil, + ExpectError: regexp.MustCompile(`expected resources_monitoring\.0\.memory\.0\.threshold to be in the range \(0 - 100\), got 101`), + }}, + }) + }) + + t.Run("DuplicatePaths", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + volume { + path = "/volume1" + enabled = true + threshold = 80 + } + volume { + path = "/volume1" + enabled = true + threshold = 100 + } + } + }`, + ExpectError: regexp.MustCompile("duplicate volume path"), + }}, + }) + }) + + t.Run("NoPath", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + volume { + enabled = true + threshold = 80 + } + } + }`, + ExpectError: regexp.MustCompile(`The argument "path" is required, but no definition was found.`), + }}, + }) + }) + + t.Run("NonAbsPath", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + volume { + path = "tmp" + enabled = true + threshold = 80 + } + } + }`, + Check: nil, + ExpectError: regexp.MustCompile(`volume path must be an absolute path`), + }}, + }) + }) + + t.Run("EmptyPath", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + volume { + path = "" + enabled = true + threshold = 80 + } + } + }`, + Check: nil, + ExpectError: regexp.MustCompile(`volume path must not be empty`), + }}, + }) + }) + + t.Run("ThresholdMissing", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + volume { + path = "/volume1" + enabled = true + } + } + }`, + Check: nil, + ExpectError: regexp.MustCompile(`The argument "threshold" is required, but no definition was found.`), + }}, + }) + }) + t.Run("EnabledMissing", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring { + memory { + threshold = 80 + } + } + }`, + Check: nil, + ExpectError: regexp.MustCompile(`The argument "enabled" is required, but no definition was found.`), + }}, + }) + }) +} + func TestAgent_MetadataDuplicateKeys(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ diff --git a/provider/examples_test.go b/provider/examples_test.go index c6931ae3..1d17b1ba 100644 --- a/provider/examples_test.go +++ b/provider/examples_test.go @@ -15,6 +15,7 @@ func TestExamples(t *testing.T) { for _, testDir := range []string{ "coder_parameter", "coder_workspace_tags", + "coder_resources_monitoring", } { t.Run(testDir, func(t *testing.T) { testDir := testDir From aef62206d070e05bd7770cedba532592cb9e42e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:18:37 +0000 Subject: [PATCH 139/173] build(deps): Bump goreleaser/goreleaser-action from 6.1.0 to 6.2.1 (#342) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 6.1.0 to 6.2.1. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/v6.1.0...v6.2.1) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6bb2f731..d85ab5e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -90,7 +90,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6.1.0 + uses: goreleaser/goreleaser-action@v6.2.1 with: version: latest args: release --clean From 4b3fc653e348c324d680c817eceeeccf06c9b877 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 13 Feb 2025 12:32:48 +0100 Subject: [PATCH 140/173] fix: app display name validation (#344) --- provider/app.go | 13 ++++++++++ provider/app_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/provider/app.go b/provider/app.go index cd64db54..2d0d6b09 100644 --- a/provider/app.go +++ b/provider/app.go @@ -23,6 +23,8 @@ var ( appSlugRegex = regexp.MustCompile(`^[a-z0-9](-?[a-z0-9])*$`) ) +const appDisplayNameMaxLength = 64 // database column limit + func appResource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, @@ -124,6 +126,17 @@ func appResource() *schema.Resource { Description: "A display name to identify the app. Defaults to the slug.", ForceNew: true, Optional: true, + ValidateDiagFunc: func(val interface{}, c cty.Path) diag.Diagnostics { + valStr, ok := val.(string) + if !ok { + return diag.Errorf("expected string, got %T", val) + } + + if len(valStr) > appDisplayNameMaxLength { + return diag.Errorf("display name is too long (max %d characters)", appDisplayNameMaxLength) + } + return nil + }, }, "subdomain": { Type: schema.TypeBool, diff --git a/provider/app_test.go b/provider/app_test.go index 005e8377..444b6b0d 100644 --- a/provider/app_test.go +++ b/provider/app_test.go @@ -415,4 +415,66 @@ func TestApp(t *testing.T) { } }) + t.Run("DisplayName", func(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + displayName string + expectValue string + expectError *regexp.Regexp + }{ + { + name: "Empty", + displayName: "", + }, + { + name: "Regular", + displayName: "Regular Application", + }, + { + name: "DisplayNameStillOK", + displayName: "0123456789012345678901234567890123456789012345678901234567890123", + }, + { + name: "DisplayNameTooLong", + displayName: "01234567890123456789012345678901234567890123456789012345678901234", + expectError: regexp.MustCompile("display name is too long"), + }, + } + + for _, c := range cases { + c := c + + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + config := fmt.Sprintf(` + provider "coder" { + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + } + resource "coder_app" "code-server" { + agent_id = coder_agent.dev.id + slug = "code-server" + display_name = "%s" + url = "http://localhost:13337" + open_in = "slim-window" + } + `, c.displayName) + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: config, + ExpectError: c.expectError, + }}, + }) + }) + } + }) + } From a9b64aab99d7815addbe25498a161c29ac1e62da Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 13 Feb 2025 13:42:47 +0100 Subject: [PATCH 141/173] fix: support unlimited parameter options (#345) --- docs/data-sources/parameter.md | 2 +- provider/parameter.go | 1 - provider/parameter_test.go | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 4da9dac2..e46cf86d 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -147,7 +147,7 @@ data "coder_parameter" "home_volume_size" { - `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! -- `option` (Block List, Max: 64) Each `option` block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) +- `option` (Block List) Each `option` block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). - `type` (String) The type of this parameter. Must be one of: `"number"`, `"string"`, `"bool"`, or `"list(string)"`. - `validation` (Block List, Max: 1) Validate the input of a parameter. (see [below for nested schema](#nestedblock--validation)) diff --git a/provider/parameter.go b/provider/parameter.go index 00dd5f34..1345f4d6 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -237,7 +237,6 @@ func parameterDataSource() *schema.Resource { Description: "Each `option` block defines a value for a user to select from.", ForceNew: true, Optional: true, - MaxItems: 64, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { diff --git a/provider/parameter_test.go b/provider/parameter_test.go index b1f164a0..7bcea8fd 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -1,7 +1,9 @@ package provider_test import ( + "fmt" "regexp" + "strings" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -816,3 +818,43 @@ func TestValueValidatesType(t *testing.T) { }) } } + +func TestParameterWithManyOptions(t *testing.T) { + t.Parallel() + + const maxItemsInTest = 1024 + + var options strings.Builder + for i := 0; i < maxItemsInTest; i++ { + _, _ = options.WriteString(fmt.Sprintf(`option { + name = "%d" + value = "%d" + } +`, i, i)) + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: fmt.Sprintf(`data "coder_parameter" "region" { + name = "Region" + type = "string" + %s + }`, options.String()), + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + param := state.Modules[0].Resources["data.coder_parameter.region"] + + for i := 0; i < maxItemsInTest; i++ { + name, _ := param.Primary.Attributes[fmt.Sprintf("option.%d.name", i)] + value, _ := param.Primary.Attributes[fmt.Sprintf("option.%d.value", i)] + require.Equal(t, fmt.Sprintf("%d", i), name) + require.Equal(t, fmt.Sprintf("%d", i), value) + } + return nil + }, + }}, + }) +} From 249863dcc1977f6ee8869e50a12929787e3e3305 Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Wed, 19 Feb 2025 17:55:06 +0500 Subject: [PATCH 142/173] chore: test auto prerelease (#347) --- .goreleaser.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 69029533..31a6b24c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -56,6 +56,8 @@ release: name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' # If you want to manually examine the release before its live, uncomment this line: # draft: true + prerelease: auto + make_latest: {{ not .Prerelease }} changelog: # see https://goreleaser.com/customization/changelog/ use: github-native From 87755fcac79b787db7c5b82593e66fb29db58fe0 Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Wed, 19 Feb 2025 18:45:52 +0500 Subject: [PATCH 143/173] chore: set GoReleaser version to 2 in config (#348) --- .github/workflows/release.yml | 2 +- .goreleaser.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d85ab5e7..82a7bb3b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,7 +92,7 @@ jobs: - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6.2.1 with: - version: latest + version: '~> v2' args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} diff --git a/.goreleaser.yml b/.goreleaser.yml index 31a6b24c..c17bc698 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,6 @@ # Visit https://goreleaser.com for documentation on how to customize this # behavior. +version: 2 before: hooks: # this is just an example and not a requirement for provider building/publishing From 72bed805debb8863657e98dae77073a0ea87f4ed Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Wed, 19 Feb 2025 19:26:26 +0500 Subject: [PATCH 144/173] chore: fix GoReleaser config for version 2 (#349) --- .goreleaser.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index c17bc698..34b92f3f 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -31,7 +31,7 @@ builds: goarch: '386' binary: '{{ .ProjectName }}_v{{ .Version }}' archives: -- format: zip +- formats: [ zip ] name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' checksum: extra_files: @@ -58,7 +58,7 @@ release: # If you want to manually examine the release before its live, uncomment this line: # draft: true prerelease: auto - make_latest: {{ not .Prerelease }} + make_latest: '{{ not .Prerelease }}' changelog: # see https://goreleaser.com/customization/changelog/ use: github-native From f95a77f8993ffb01bb90c051f38a5ef4ed93716f Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Wed, 5 Mar 2025 13:49:15 +0500 Subject: [PATCH 145/173] chore: do not use GitHub prereleases (#355) --- .goreleaser.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 34b92f3f..658a715c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -55,10 +55,6 @@ release: extra_files: - glob: 'terraform-registry-manifest.json' name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' - # If you want to manually examine the release before its live, uncomment this line: - # draft: true - prerelease: auto - make_latest: '{{ not .Prerelease }}' changelog: # see https://goreleaser.com/customization/changelog/ use: github-native From 68f7cf0346c636298844b947ef2d7b5b09d8a0f2 Mon Sep 17 00:00:00 2001 From: M Atif Ali Date: Wed, 5 Mar 2025 14:04:42 +0500 Subject: [PATCH 146/173] chore: include terraform 1.11.* in tests (#356) --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 88ccde05..8e4df55d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,6 +90,7 @@ jobs: terraform: - "1.9.*" - "1.10.*" + - "1.11.*" steps: - name: Set up Go uses: actions/setup-go@v5 From ea1c3d7bf71e739a01a4655897cde23d5d8b4c8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 09:13:59 +0000 Subject: [PATCH 147/173] build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 (#351) Bumps [github.com/hashicorp/terraform-plugin-sdk/v2](https://github.com/hashicorp/terraform-plugin-sdk) from 2.36.0 to 2.36.1. - [Release notes](https://github.com/hashicorp/terraform-plugin-sdk/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-sdk/compare/v2.36.0...v2.36.1) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-sdk/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index c1033b5e..02ea7137 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 @@ -79,11 +79,11 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/otel/trace v1.31.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.33.0 // indirect golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index a8819092..2b5ad9c5 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,8 @@ github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiy github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 h1:7/iejAPyCRBhqAg3jOx+4UcAhY0A+Sg8B+0+d/GxSfM= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0/go.mod h1:TiQwXAjFrgBf5tg5rvBRz8/ubPULpU0HjSaVi5UoJf8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 h1:WNMsTLkZf/3ydlgsuXePa3jvZFwAJhruxTxP/c1Viuw= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1/go.mod h1:P6o64QS97plG44iFzSM6rAn6VJIC/Sy9a9IkEtl79K4= github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA= github.com/hashicorp/terraform-registry-address v0.2.4/go.mod h1:tUNYTVyCtU4OIGXXMDp7WNcJ+0W1B4nmstVDgHMjfAU= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -225,8 +225,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -247,8 +247,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -263,8 +263,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -272,8 +272,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 552eb5e9a1a564f19cd3ba3745f2abb5d205e74c Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Wed, 5 Mar 2025 11:18:00 +0200 Subject: [PATCH 148/173] chore: only release if tests pass (#357) We've generally been lucky that builds are slower than integration tests, but we need explicit ordering here Signed-off-by: Danny Kopping --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 82a7bb3b..33f17b8d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,6 +69,7 @@ jobs: goreleaser: runs-on: ubuntu-latest + needs: test steps: - name: Checkout uses: actions/checkout@v4 From eab8698d5b34d712a15cbaa99addf3698aa87577 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 14 Mar 2025 14:40:14 -0400 Subject: [PATCH 149/173] feat: Add rbac_roles to coder_workspace_owner data source (#330) --- docs/data-sources/workspace_owner.md | 1 + integration/integration_test.go | 2 ++ integration/workspace-owner-filled/main.tf | 1 + integration/workspace-owner/main.tf | 1 + provider/workspace_owner.go | 27 ++++++++++++++++++++++ provider/workspace_owner_test.go | 6 ++++- 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index fbe4f205..71e39ed1 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -53,6 +53,7 @@ resource "coder_env" "git_author_email" { - `login_type` (String) The type of login the user has. - `name` (String) The username of the user. - `oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. +- `rbac_roles` (List of Map) The RBAC roles and associated org ids of which the user is assigned. - `session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated every time a workspace is started. - `ssh_private_key` (String, Sensitive) The user's generated SSH private key. - `ssh_public_key` (String) The user's generated SSH public key. diff --git a/integration/integration_test.go b/integration/integration_test.go index bbbd5587..89fdda7e 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -122,6 +122,7 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, "workspace_owner.login_type": ``, + "workspace_owner.rbac_roles": `\[\]`, }, }, { @@ -150,6 +151,7 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, "workspace_owner.login_type": `password`, + "workspace_owner.rbac_roles": `\[\]`, }, }, { diff --git a/integration/workspace-owner-filled/main.tf b/integration/workspace-owner-filled/main.tf index fd923a3d..d2de5661 100644 --- a/integration/workspace-owner-filled/main.tf +++ b/integration/workspace-owner-filled/main.tf @@ -40,6 +40,7 @@ locals { "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, + "workspace_owner.rbac_roles" : jsonencode(data.coder_workspace_owner.me.rbac_roles), } } diff --git a/integration/workspace-owner/main.tf b/integration/workspace-owner/main.tf index fd923a3d..d2de5661 100644 --- a/integration/workspace-owner/main.tf +++ b/integration/workspace-owner/main.tf @@ -40,6 +40,7 @@ locals { "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, + "workspace_owner.rbac_roles" : jsonencode(data.coder_workspace_owner.me.rbac_roles), } } diff --git a/provider/workspace_owner.go b/provider/workspace_owner.go index 52b1ef8c..078047ff 100644 --- a/provider/workspace_owner.go +++ b/provider/workspace_owner.go @@ -59,6 +59,14 @@ func workspaceOwnerDataSource() *schema.Resource { _ = rd.Set("login_type", loginType) } + var rbacRoles []map[string]string + if rolesRaw, ok := os.LookupEnv("CODER_WORKSPACE_OWNER_RBAC_ROLES"); ok { + if err := json.NewDecoder(strings.NewReader(rolesRaw)).Decode(&rbacRoles); err != nil { + return diag.Errorf("invalid user rbac roles: %s", err.Error()) + } + } + _ = rd.Set("rbac_roles", rbacRoles) + return diags }, Schema: map[string]*schema.Schema{ @@ -118,6 +126,25 @@ func workspaceOwnerDataSource() *schema.Resource { Computed: true, Description: "The type of login the user has.", }, + "rbac_roles": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the RBAC role.", + }, + "org_id": { + Type: schema.TypeString, + Computed: true, + Description: "The organization ID associated with the RBAC role.", + }, + }, + }, + Computed: true, + Description: "The RBAC roles of which the user is assigned.", + }, }, } } diff --git a/provider/workspace_owner_test.go b/provider/workspace_owner_test.go index ad371570..de23b3e7 100644 --- a/provider/workspace_owner_test.go +++ b/provider/workspace_owner_test.go @@ -34,6 +34,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", `supersecret`) t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", `alsosupersecret`) t.Setenv("CODER_WORKSPACE_OWNER_LOGIN_TYPE", `github`) + t.Setenv("CODER_WORKSPACE_OWNER_RBAC_ROLES", `[{"name":"member","org_id":"00000000-0000-0000-0000-000000000000"}]`) resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(), @@ -61,7 +62,8 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { assert.Equal(t, `supersecret`, attrs["session_token"]) assert.Equal(t, `alsosupersecret`, attrs["oidc_access_token"]) assert.Equal(t, `github`, attrs["login_type"]) - + assert.Equal(t, `member`, attrs["rbac_roles.0.name"]) + assert.Equal(t, `00000000-0000-0000-0000-000000000000`, attrs["rbac_roles.0.org_id"]) return nil }, }}, @@ -80,6 +82,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { "CODER_WORKSPACE_OWNER_SSH_PUBLIC_KEY", "CODER_WORKSPACE_OWNER_SSH_PRIVATE_KEY", "CODER_WORKSPACE_OWNER_LOGIN_TYPE", + "CODER_WORKSPACE_OWNER_RBAC_ROLES", } { // https://github.com/golang/go/issues/52817 t.Setenv(v, "") os.Unsetenv(v) @@ -110,6 +113,7 @@ func TestWorkspaceOwnerDatasource(t *testing.T) { assert.Empty(t, attrs["session_token"]) assert.Empty(t, attrs["oidc_access_token"]) assert.Empty(t, attrs["login_type"]) + assert.Empty(t, attrs["rbac_roles.0"]) return nil }, }}, From f75fb0b273851decf878920d04d12f16e7e9d743 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 19 Mar 2025 14:53:20 +0000 Subject: [PATCH 150/173] chore(integration): fix failing tests referencing workspace_owner.rbac_roles (#369) --- docs/data-sources/workspace_owner.md | 10 +++- integration/integration_test.go | 33 ++++++++++- .../workspace-owner-rbac-roles/main.tf | 57 +++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 integration/workspace-owner-rbac-roles/main.tf diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index 71e39ed1..2a912e1f 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -53,7 +53,15 @@ resource "coder_env" "git_author_email" { - `login_type` (String) The type of login the user has. - `name` (String) The username of the user. - `oidc_access_token` (String) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `rbac_roles` (List of Map) The RBAC roles and associated org ids of which the user is assigned. +- `rbac_roles` (List of Object) The RBAC roles of which the user is assigned. (see [below for nested schema](#nestedatt--rbac_roles)) - `session_token` (String) Session token for authenticating with a Coder deployment. It is regenerated every time a workspace is started. - `ssh_private_key` (String, Sensitive) The user's generated SSH private key. - `ssh_public_key` (String) The user's generated SSH public key. + + +### Nested Schema for `rbac_roles` + +Read-Only: + +- `name` (String) +- `org_id` (String) diff --git a/integration/integration_test.go b/integration/integration_test.go index 89fdda7e..65aa5aed 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -122,7 +122,7 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, "workspace_owner.login_type": ``, - "workspace_owner.rbac_roles": `\[\]`, + "workspace_owner.rbac_roles": ``, }, }, { @@ -151,7 +151,36 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, "workspace_owner.login_type": `password`, - "workspace_owner.rbac_roles": `\[\]`, + "workspace_owner.rbac_roles": ``, + }, + }, + { + name: "workspace-owner-rbac-roles", + minVersion: "v2.21.0", // anticipated version, update as required + expectedOutput: map[string]string{ + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": ``, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `workspace-owner`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, + "workspace_owner.email": `testing@coder\.com`, + "workspace_owner.full_name": `default`, + "workspace_owner.groups": `\[(\"Everyone\")?\]`, + "workspace_owner.id": `[a-zA-Z0-9-]+`, + "workspace_owner.name": `testing`, + "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration + "workspace_owner.session_token": `.+`, + "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, + "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, + "workspace_owner.login_type": `password`, + "workspace_owner.rbac_roles": `(?is)\[(\{"name":"[a-z0-9-:]+","org_id":"[a-f0-9-]+"\},?)+\]`, }, }, { diff --git a/integration/workspace-owner-rbac-roles/main.tf b/integration/workspace-owner-rbac-roles/main.tf new file mode 100644 index 00000000..66b79282 --- /dev/null +++ b/integration/workspace-owner-rbac-roles/main.tf @@ -0,0 +1,57 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +locals { + # NOTE: these must all be strings in the output + output = { + "provisioner.arch" : data.coder_provisioner.me.arch, + "provisioner.id" : data.coder_provisioner.me.id, + "provisioner.os" : data.coder_provisioner.me.os, + "workspace.access_port" : tostring(data.coder_workspace.me.access_port), + "workspace.access_url" : data.coder_workspace.me.access_url, + "workspace.id" : data.coder_workspace.me.id, + "workspace.name" : data.coder_workspace.me.name, + "workspace.start_count" : tostring(data.coder_workspace.me.start_count), + "workspace.template_id" : data.coder_workspace.me.template_id, + "workspace.template_name" : data.coder_workspace.me.template_name, + "workspace.template_version" : data.coder_workspace.me.template_version, + "workspace.transition" : data.coder_workspace.me.transition, + "workspace_owner.email" : data.coder_workspace_owner.me.email, + "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, + "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), + "workspace_owner.id" : data.coder_workspace_owner.me.id, + "workspace_owner.name" : data.coder_workspace_owner.me.name, + "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, + "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, + "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, + "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, + "workspace_owner.rbac_roles" : jsonencode(data.coder_workspace_owner.me.rbac_roles), + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} From 9a745586b23a9cb5de2f65a2dcac12e48b134ffa Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Thu, 20 Mar 2025 19:09:06 +0200 Subject: [PATCH 151/173] feat: add `coder_devcontainer` resource (#368) * feat: add `coder_devcontainer` resource This change will allow autostarting Dev Containers. This is implemented as a resource instead of a `schema.TypeSet` on the agent resource to allow definition via Coder modules. Updates coder/coder#16423 --- docs/resources/devcontainer.md | 29 ++++++++++ provider/devcontainer.go | 46 ++++++++++++++++ provider/devcontainer_test.go | 98 ++++++++++++++++++++++++++++++++++ provider/provider.go | 1 + 4 files changed, 174 insertions(+) create mode 100644 docs/resources/devcontainer.md create mode 100644 provider/devcontainer.go create mode 100644 provider/devcontainer_test.go diff --git a/docs/resources/devcontainer.md b/docs/resources/devcontainer.md new file mode 100644 index 00000000..93d5724b --- /dev/null +++ b/docs/resources/devcontainer.md @@ -0,0 +1,29 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_devcontainer Resource - terraform-provider-coder" +subcategory: "" +description: |- + Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21). +--- + +# coder_devcontainer (Resource) + +Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21). + + + + +## Schema + +### Required + +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. +- `workspace_folder` (String) The workspace folder to for the Dev Container. + +### Optional + +- `config_path` (String) The path to the Dev Container configuration file (devcontainer.json). + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/provider/devcontainer.go b/provider/devcontainer.go new file mode 100644 index 00000000..7d1fe0a4 --- /dev/null +++ b/provider/devcontainer.go @@ -0,0 +1,46 @@ +package provider + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func devcontainerResource() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Description: "Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21).", + CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { + rd.SetId(uuid.NewString()) + + return nil + }, + ReadContext: schema.NoopContext, + DeleteContext: schema.NoopContext, + Schema: map[string]*schema.Schema{ + "agent_id": { + Type: schema.TypeString, + Description: "The `id` property of a `coder_agent` resource to associate with.", + ForceNew: true, + Required: true, + }, + "workspace_folder": { + Type: schema.TypeString, + Description: "The workspace folder to for the Dev Container.", + ForceNew: true, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "config_path": { + Type: schema.TypeString, + Description: "The path to the Dev Container configuration file (devcontainer.json).", + ForceNew: true, + Optional: true, + }, + }, + } +} diff --git a/provider/devcontainer_test.go b/provider/devcontainer_test.go new file mode 100644 index 00000000..784cfb0d --- /dev/null +++ b/provider/devcontainer_test.go @@ -0,0 +1,98 @@ +package provider_test + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestDevcontainer(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "king" + workspace_folder = "/workspace" + config_path = "/workspace/devcontainer.json" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_devcontainer.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "workspace_folder": "/workspace", + "config_path": "/workspace/devcontainer.json", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestDevcontainerNoConfigPath(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "king" + workspace_folder = "/workspace" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_devcontainer.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "workspace_folder": "/workspace", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestDevcontainerNoWorkspaceFolder(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "" + } + `, + ExpectError: regexp.MustCompile(`The argument "workspace_folder" is required, but no definition was found.`), + }}, + }) +} diff --git a/provider/provider.go b/provider/provider.go index d9780d76..cc2644ef 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -76,6 +76,7 @@ func New() *schema.Provider { "coder_metadata": metadataResource(), "coder_script": scriptResource(), "coder_env": envResource(), + "coder_devcontainer": devcontainerResource(), }, } } From ef92eea9d88a63ecda165a3f17f891845d3a7da2 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Mon, 7 Apr 2025 08:20:00 +0200 Subject: [PATCH 152/173] feat: allow presets to define prebuilds (#373) * feat: allow presets to define prebuilds * document prebuild parameters * remove todo * make gen * Add integration testing * Allow presets to define 0 parameters * additional documentation for prebuilds --- README.md | 2 +- docs/data-sources/workspace.md | 2 ++ docs/data-sources/workspace_preset.md | 21 +++++++++--- integration/integration_test.go | 9 ++--- integration/test-data-source/main.tf | 5 +++ provider/workspace.go | 22 +++++++++++++ provider/workspace_preset.go | 47 ++++++++++++++++++++------- provider/workspace_preset_test.go | 40 +++++++++++++++++++++-- 8 files changed, 124 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b8ee8840..f055961e 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ to setup your local Terraform to use your local version rather than the registry } ``` 2. Run `terraform init` and observe a warning like `Warning: Provider development overrides are in effect` -4. Run `go build -o terraform-provider-coder` to build the provider binary, which Terraform will try locate and execute +4. Run `make build` to build the provider binary, which Terraform will try locate and execute 5. All local Terraform runs will now use your local provider! 6. _**NOTE**: we vendor in this provider into `github.com/coder/coder`, so if you're testing with a local clone then you should also run `go mod edit -replace github.com/coder/terraform-provider-coder=/path/to/terraform-provider-coder` in your clone._ diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 26396ba1..29fd9179 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -69,7 +69,9 @@ resource "docker_container" "workspace" { - `access_port` (Number) The access port of the Coder deployment provisioning this workspace. - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. +- `is_prebuild` (Boolean) Similar to `prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false. - `name` (String) Name of the workspace. +- `prebuild_count` (Number) A computed count, equal to 1 if the workspace is a currently unassigned prebuild. Use this to conditionally act on the status of a prebuild. Actions that do not require user identity can be taken when this value is set to 1. Actions that should only be taken once the workspace has been assigned to a user may be taken when this value is set to 0. - `start_count` (Number) A computed count based on `transition` state. If `start`, count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index 28f90faa..edd61f18 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -3,12 +3,12 @@ page_title: "coder_workspace_preset Data Source - terraform-provider-coder" subcategory: "" description: |- - Use this data source to predefine common configurations for workspaces. + Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace. --- # coder_workspace_preset (Data Source) -Use this data source to predefine common configurations for workspaces. +Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace. ## Example Usage @@ -34,9 +34,20 @@ data "coder_workspace_preset" "example" { ### Required -- `name` (String) Name of the workspace preset. -- `parameters` (Map of String) Parameters of the workspace preset. +- `name` (String) The name of the workspace preset. + +### Optional + +- `parameters` (Map of String) Workspace parameters that will be set by the workspace preset. For simple templates that only need prebuilds, you may define a preset with zero parameters. Because workspace parameters may change between Coder template versions, preset parameters are allowed to define values for parameters that do not exist in the current template version. +- `prebuilds` (Block Set, Max: 1) Prebuilt workspace configuration related to this workspace preset. Coder will build and maintain workspaces in reserve based on this configuration. When a user creates a new workspace using a preset, they will be assigned a prebuilt workspace, instead of waiting for a new workspace to build. (see [below for nested schema](#nestedblock--prebuilds)) ### Read-Only -- `id` (String) ID of the workspace preset. +- `id` (String) The preset ID is automatically generated and may change between runs. It is recommended to use the `name` attribute to identify the preset. + + +### Nested Schema for `prebuilds` + +Required: + +- `instances` (Number) The number of workspaces to keep in reserve for this preset. diff --git a/integration/integration_test.go b/integration/integration_test.go index 65aa5aed..9803aa41 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -90,10 +90,11 @@ func TestIntegration(t *testing.T) { // TODO (sasswart): the cli doesn't support presets yet. // once it does, the value for workspace_parameter.value // will be the preset value. - "workspace_parameter.value": `param value`, - "workspace_parameter.icon": `param icon`, - "workspace_preset.name": `preset`, - "workspace_preset.parameters.param": `preset param value`, + "workspace_parameter.value": `param value`, + "workspace_parameter.icon": `param icon`, + "workspace_preset.name": `preset`, + "workspace_preset.parameters.param": `preset param value`, + "workspace_preset.prebuilds.instances": `1`, }, }, { diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 5fb2e0e6..f18fa347 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -24,6 +24,10 @@ data "coder_workspace_preset" "preset" { parameters = { (data.coder_parameter.param.name) = "preset param value" } + + prebuilds { + instances = 1 + } } locals { @@ -47,6 +51,7 @@ locals { "workspace_parameter.icon" : data.coder_parameter.param.icon, "workspace_preset.name" : data.coder_workspace_preset.preset.name, "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, + "workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances), } } diff --git a/provider/workspace.go b/provider/workspace.go index fde742b6..5ddd3ee8 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -27,6 +27,14 @@ func workspaceDataSource() *schema.Resource { } _ = rd.Set("start_count", count) + prebuild := helpers.OptionalEnv(IsPrebuildEnvironmentVariable()) + prebuildCount := 0 + if prebuild == "true" { + prebuildCount = 1 + _ = rd.Set("is_prebuild", true) + } + _ = rd.Set("prebuild_count", prebuildCount) + name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) @@ -83,6 +91,11 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "The access port of the Coder deployment provisioning this workspace.", }, + "prebuild_count": { + Type: schema.TypeInt, + Computed: true, + Description: "A computed count, equal to 1 if the workspace is a currently unassigned prebuild. Use this to conditionally act on the status of a prebuild. Actions that do not require user identity can be taken when this value is set to 1. Actions that should only be taken once the workspace has been assigned to a user may be taken when this value is set to 0.", + }, "start_count": { Type: schema.TypeInt, Computed: true, @@ -98,6 +111,11 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "UUID of the workspace.", }, + "is_prebuild": { + Type: schema.TypeBool, + Computed: true, + Description: "Similar to `prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false.", + }, "name": { Type: schema.TypeString, Computed: true, @@ -121,3 +139,7 @@ func workspaceDataSource() *schema.Resource { }, } } + +func IsPrebuildEnvironmentVariable() string { + return "CODER_WORKSPACE_IS_PREBUILD" +} diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index cd56c980..004489e7 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -12,33 +12,39 @@ import ( type WorkspacePreset struct { Name string `mapstructure:"name"` Parameters map[string]string `mapstructure:"parameters"` + Prebuilds WorkspacePrebuild `mapstructure:"prebuilds"` +} + +type WorkspacePrebuild struct { + Instances int `mapstructure:"instances"` } func workspacePresetDataSource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, - Description: "Use this data source to predefine common configurations for workspaces.", + Description: "Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace.", ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { var preset WorkspacePreset err := mapstructure.Decode(struct { Name interface{} Parameters interface{} + Prebuilds struct { + Instances interface{} + } }{ Name: rd.Get("name"), Parameters: rd.Get("parameters"), + Prebuilds: struct { + Instances interface{} + }{ + Instances: rd.Get("prebuilds.0.instances"), + }, }, &preset) if err != nil { return diag.Errorf("decode workspace preset: %s", err) } - // MinItems doesn't work with maps, so we need to check the length - // of the map manually. All other validation is handled by the - // schema. - if len(preset.Parameters) == 0 { - return diag.Errorf("expected \"parameters\" to not be an empty map") - } - rd.SetId(preset.Name) return nil @@ -46,25 +52,42 @@ func workspacePresetDataSource() *schema.Resource { Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, - Description: "ID of the workspace preset.", + Description: "The preset ID is automatically generated and may change between runs. It is recommended to use the `name` attribute to identify the preset.", Computed: true, }, "name": { Type: schema.TypeString, - Description: "Name of the workspace preset.", + Description: "The name of the workspace preset.", Required: true, ValidateFunc: validation.StringIsNotEmpty, }, "parameters": { Type: schema.TypeMap, - Description: "Parameters of the workspace preset.", - Required: true, + Description: "Workspace parameters that will be set by the workspace preset. For simple templates that only need prebuilds, you may define a preset with zero parameters. Because workspace parameters may change between Coder template versions, preset parameters are allowed to define values for parameters that do not exist in the current template version.", + Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, Required: true, ValidateFunc: validation.StringIsNotEmpty, }, }, + "prebuilds": { + Type: schema.TypeSet, + Description: "Prebuilt workspace configuration related to this workspace preset. Coder will build and maintain workspaces in reserve based on this configuration. When a user creates a new workspace using a preset, they will be assigned a prebuilt workspace, instead of waiting for a new workspace to build.", + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "instances": { + Type: schema.TypeInt, + Description: "The number of workspaces to keep in reserve for this preset.", + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(0), + }, + }, + }, + }, }, } } diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 876e2044..aa1ca0ce 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -84,7 +84,7 @@ func TestWorkspacePreset(t *testing.T) { }`, // This validation is done by Terraform, but it could still break if we misconfigure the schema. // So we test it here to make sure we don't regress. - ExpectError: regexp.MustCompile("The argument \"parameters\" is required, but no definition was found"), + ExpectError: nil, }, { Name: "Parameters field is empty", @@ -95,7 +95,7 @@ func TestWorkspacePreset(t *testing.T) { }`, // This validation is *not* done by Terraform, because MinItems doesn't work with maps. // We've implemented the validation in ReadContext, so we test it here to make sure we don't regress. - ExpectError: regexp.MustCompile("expected \"parameters\" to not be an empty map"), + ExpectError: nil, }, { Name: "Parameters field is not a map", @@ -108,6 +108,42 @@ func TestWorkspacePreset(t *testing.T) { // So we test it here to make sure we don't regress. ExpectError: regexp.MustCompile("Inappropriate value for attribute \"parameters\": map of string required"), }, + { + Name: "Prebuilds is set, but not its required fields", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds {} + }`, + ExpectError: regexp.MustCompile("The argument \"instances\" is required, but no definition was found."), + }, + { + Name: "Prebuilds is set, and so are its required fields", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + parameters = { + "region" = "us-east1-a" + } + prebuilds { + instances = 1 + } + }`, + ExpectError: nil, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_workspace_preset.preset_1"] + require.NotNil(t, resource) + attrs := resource.Primary.Attributes + require.Equal(t, attrs["name"], "preset_1") + require.Equal(t, attrs["prebuilds.0.instances"], "1") + return nil + }, + }, } for _, testcase := range testcases { From 3a2c18dab13ebd36ddab31a97e2c566696b1d3e3 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Mon, 7 Apr 2025 09:55:38 +0200 Subject: [PATCH 153/173] Correct the prebuilds type (#376) --- provider/workspace_preset.go | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 004489e7..2fab0b8a 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -12,7 +12,12 @@ import ( type WorkspacePreset struct { Name string `mapstructure:"name"` Parameters map[string]string `mapstructure:"parameters"` - Prebuilds WorkspacePrebuild `mapstructure:"prebuilds"` + // There should always be only one prebuild block, but Terraform's type system + // still parses them as a slice, so we need to handle it as such. We could use + // an anonymous type and rd.Get to avoid a slice here, but that would not be possible + // for utilities that parse our terraform output using this type. To remain compatible + // with those cases, we use a slice here. + Prebuilds []WorkspacePrebuild `mapstructure:"prebuilds"` } type WorkspacePrebuild struct { @@ -27,19 +32,9 @@ func workspacePresetDataSource() *schema.Resource { ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { var preset WorkspacePreset err := mapstructure.Decode(struct { - Name interface{} - Parameters interface{} - Prebuilds struct { - Instances interface{} - } + Name interface{} }{ - Name: rd.Get("name"), - Parameters: rd.Get("parameters"), - Prebuilds: struct { - Instances interface{} - }{ - Instances: rd.Get("prebuilds.0.instances"), - }, + Name: rd.Get("name"), }, &preset) if err != nil { return diag.Errorf("decode workspace preset: %s", err) From 8804c44f070b366bb29e0e4b8d44b6eba9473b0c Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Tue, 8 Apr 2025 13:04:02 -0500 Subject: [PATCH 154/173] feat: `form_type` and `styling` metadata arguments added (#375) Adds `form_type` as a field to parameters. By default, legacy behavior is maintained by deducing the default `form_type` value from the existing inputs. `styling` argument also added for cosmetic usage on the frontend form --- docs/data-sources/parameter.md | 2 + provider/formtype.go | 148 ++++++++++++ provider/formtype_test.go | 428 +++++++++++++++++++++++++++++++++ provider/parameter.go | 94 ++++++-- provider/parameter_test.go | 17 +- 5 files changed, 664 insertions(+), 25 deletions(-) create mode 100644 provider/formtype.go create mode 100644 provider/formtype_test.go diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index e46cf86d..934ae77a 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -145,10 +145,12 @@ data "coder_parameter" "home_volume_size" { - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. - `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. +- `form_type` (String) The type of this parameter. Must be one of: [radio, slider, input, dropdown, checkbox, switch, multi-select, tag-select, textarea, error]. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons [here](https://github.com/coder/coder/tree/main/site/static/icon). Use a built-in icon with `"${data.coder_workspace.me.access_url}/icon/"`. - `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution! - `option` (Block List) Each `option` block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option)) - `order` (Number) The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order). +- `styling` (String) JSON encoded string containing the metadata for controlling the appearance of this parameter in the UI. This option is purely cosmetic and does not affect the function of the parameter in terraform. - `type` (String) The type of this parameter. Must be one of: `"number"`, `"string"`, `"bool"`, or `"list(string)"`. - `validation` (Block List, Max: 1) Validate the input of a parameter. (see [below for nested schema](#nestedblock--validation)) diff --git a/provider/formtype.go b/provider/formtype.go new file mode 100644 index 00000000..48fbeed3 --- /dev/null +++ b/provider/formtype.go @@ -0,0 +1,148 @@ +package provider + +import ( + "slices" + + "golang.org/x/xerrors" +) + +// OptionType is a type of option that can be used in the 'type' argument of +// a parameter. These should match types as defined in terraform: +// +// https://developer.hashicorp.com/terraform/language/expressions/types +// +// The value have to be string literals, as type constraint keywords are not +// supported in providers. +type OptionType string + +const ( + OptionTypeString OptionType = "string" + OptionTypeNumber OptionType = "number" + OptionTypeBoolean OptionType = "bool" + OptionTypeListString OptionType = "list(string)" +) + +func OptionTypes() []OptionType { + return []OptionType{ + OptionTypeString, + OptionTypeNumber, + OptionTypeBoolean, + OptionTypeListString, + } +} + +// ParameterFormType is the list of supported form types for display in +// the Coder "create workspace" form. These form types are functional as well +// as cosmetic. Refer to `formTypeTruthTable` for the allowed pairings. +// For example, "multi-select" has the type "list(string)" but the option +// values are "string". +type ParameterFormType string + +const ( + ParameterFormTypeDefault ParameterFormType = "" + ParameterFormTypeRadio ParameterFormType = "radio" + ParameterFormTypeSlider ParameterFormType = "slider" + ParameterFormTypeInput ParameterFormType = "input" + ParameterFormTypeDropdown ParameterFormType = "dropdown" + ParameterFormTypeCheckbox ParameterFormType = "checkbox" + ParameterFormTypeSwitch ParameterFormType = "switch" + ParameterFormTypeMultiSelect ParameterFormType = "multi-select" + ParameterFormTypeTagSelect ParameterFormType = "tag-select" + ParameterFormTypeTextArea ParameterFormType = "textarea" + ParameterFormTypeError ParameterFormType = "error" +) + +// ParameterFormTypes should be kept in sync with the enum list above. +func ParameterFormTypes() []ParameterFormType { + return []ParameterFormType{ + // Intentionally omit "ParameterFormTypeDefault" from this set. + // It is a valid enum, but will always be mapped to a real value when + // being used. + ParameterFormTypeRadio, + ParameterFormTypeSlider, + ParameterFormTypeInput, + ParameterFormTypeDropdown, + ParameterFormTypeCheckbox, + ParameterFormTypeSwitch, + ParameterFormTypeMultiSelect, + ParameterFormTypeTagSelect, + ParameterFormTypeTextArea, + ParameterFormTypeError, + } +} + +// formTypeTruthTable is a map of [`type`][`optionCount` > 0] to `form_type`. +// The first value in the slice is the default value assuming `form_type` is +// not specified. +// +// The boolean key indicates whether the `options` field is specified. +// | Type | Options | Specified Form Type | form_type | Notes | +// |-------------------|---------|---------------------|----------------|--------------------------------| +// | `string` `number` | Y | | `radio` | | +// | `string` `number` | Y | `dropdown` | `dropdown` | | +// | `string` `number` | N | | `input` | | +// | `string` | N | 'textarea' | `textarea` | | +// | `number` | N | 'slider' | `slider` | min/max validation | +// | `bool` | Y | | `radio` | | +// | `bool` | N | | `checkbox` | | +// | `bool` | N | `switch` | `switch` | | +// | `list(string)` | Y | | `radio` | | +// | `list(string)` | N | | `tag-select` | | +// | `list(string)` | Y | `multi-select` | `multi-select` | Option values will be `string` | +var formTypeTruthTable = map[OptionType]map[bool][]ParameterFormType{ + OptionTypeString: { + true: {ParameterFormTypeRadio, ParameterFormTypeDropdown}, + false: {ParameterFormTypeInput, ParameterFormTypeTextArea}, + }, + OptionTypeNumber: { + true: {ParameterFormTypeRadio, ParameterFormTypeDropdown}, + false: {ParameterFormTypeInput, ParameterFormTypeSlider}, + }, + OptionTypeBoolean: { + true: {ParameterFormTypeRadio}, + false: {ParameterFormTypeCheckbox, ParameterFormTypeSwitch}, + }, + OptionTypeListString: { + true: {ParameterFormTypeRadio, ParameterFormTypeMultiSelect}, + false: {ParameterFormTypeTagSelect}, + }, +} + +// ValidateFormType handles the truth table for the valid set of `type` and +// `form_type` options. +// The OptionType is also returned because it is possible the 'type' of the +// 'value' & 'default' fields is different from the 'type' of the options. +// The use case is when using multi-select. The options are 'string' and the +// value is 'list(string)'. +func ValidateFormType(paramType OptionType, optionCount int, specifiedFormType ParameterFormType) (OptionType, ParameterFormType, error) { + allowed, ok := formTypeTruthTable[paramType][optionCount > 0] + if !ok || len(allowed) == 0 { + return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", paramType) + } + + if specifiedFormType == ParameterFormTypeDefault { + // handle the default case + specifiedFormType = allowed[0] + } + + if !slices.Contains(allowed, specifiedFormType) { + return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", specifiedFormType) + } + + // This is the only current special case. If 'multi-select' is selected, the type + // of 'value' and an options 'value' are different. The type of the parameter is + // `list(string)` but the type of the individual options is `string`. + if paramType == OptionTypeListString && specifiedFormType == ParameterFormTypeMultiSelect { + return OptionTypeString, ParameterFormTypeMultiSelect, nil + } + + return paramType, specifiedFormType, nil +} + +func toStrings[A ~string](l []A) []string { + var r []string + for _, v := range l { + r = append(r, string(v)) + } + return r +} diff --git a/provider/formtype_test.go b/provider/formtype_test.go new file mode 100644 index 00000000..599c2e41 --- /dev/null +++ b/provider/formtype_test.go @@ -0,0 +1,428 @@ +package provider_test + +import ( + "encoding/json" + "fmt" + "regexp" + "strconv" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/coder/terraform-provider-coder/v2/provider" +) + +// formTypeTestCase is the config for a single test case. +type formTypeTestCase struct { + name string + config formTypeCheck + assert paramAssert + expectError *regexp.Regexp +} + +// paramAssert is asserted on the provider's parsed terraform state. +type paramAssert struct { + FormType provider.ParameterFormType + Type provider.OptionType + Styling json.RawMessage +} + +// formTypeCheck is a struct that helps build the terraform config +type formTypeCheck struct { + formType provider.ParameterFormType + optionType provider.OptionType + options bool + + // optional to inform the assert + customOptions []string + defValue string + styling json.RawMessage +} + +func (c formTypeCheck) String() string { + return fmt.Sprintf("%s_%s_%t", c.formType, c.optionType, c.options) +} + +func TestValidateFormType(t *testing.T) { + t.Parallel() + + // formTypesChecked keeps track of all checks run. It will be used to + // ensure all combinations of form_type and option_type are tested. + // All untested options are assumed to throw an error. + formTypesChecked := make(map[string]struct{}) + + expectType := func(expected provider.ParameterFormType, opts formTypeCheck) formTypeTestCase { + ftname := opts.formType + if ftname == "" { + ftname = "default" + } + + if opts.styling == nil { + // Try passing arbitrary data in, as anything should be accepted + opts.styling, _ = json.Marshal(map[string]any{ + "foo": "bar", + "disabled": true, + "nested": map[string]any{ + "foo": "bar", + }, + }) + } + + return formTypeTestCase{ + name: fmt.Sprintf("%s_%s_%t", + ftname, + opts.optionType, + opts.options, + ), + config: opts, + assert: paramAssert{ + FormType: expected, + Type: opts.optionType, + Styling: opts.styling, + }, + expectError: nil, + } + } + + // expectSameFormType just assumes the FormType in the check is the expected + // FormType. Using `expectType` these fields can differ + expectSameFormType := func(opts formTypeCheck) formTypeTestCase { + return expectType(opts.formType, opts) + } + + cases := []formTypeTestCase{ + { + // When nothing is specified + name: "defaults", + config: formTypeCheck{}, + assert: paramAssert{ + FormType: provider.ParameterFormTypeInput, + Type: provider.OptionTypeString, + Styling: []byte("{}"), + }, + }, + // All default behaviors. Essentially legacy behavior. + // String + expectType(provider.ParameterFormTypeRadio, formTypeCheck{ + options: true, + optionType: provider.OptionTypeString, + }), + expectType(provider.ParameterFormTypeInput, formTypeCheck{ + options: false, + optionType: provider.OptionTypeString, + }), + // Number + expectType(provider.ParameterFormTypeRadio, formTypeCheck{ + options: true, + optionType: provider.OptionTypeNumber, + }), + expectType(provider.ParameterFormTypeInput, formTypeCheck{ + options: false, + optionType: provider.OptionTypeNumber, + }), + // Boolean + expectType(provider.ParameterFormTypeRadio, formTypeCheck{ + options: true, + optionType: provider.OptionTypeBoolean, + }), + expectType(provider.ParameterFormTypeCheckbox, formTypeCheck{ + options: false, + optionType: provider.OptionTypeBoolean, + }), + // List(string) + expectType(provider.ParameterFormTypeRadio, formTypeCheck{ + options: true, + optionType: provider.OptionTypeListString, + }), + expectType(provider.ParameterFormTypeTagSelect, formTypeCheck{ + options: false, + optionType: provider.OptionTypeListString, + }), + + // ---- New Behavior + // String + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeString, + formType: provider.ParameterFormTypeDropdown, + }), + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeString, + formType: provider.ParameterFormTypeRadio, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeString, + formType: provider.ParameterFormTypeInput, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeString, + formType: provider.ParameterFormTypeTextArea, + }), + // Number + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeNumber, + formType: provider.ParameterFormTypeDropdown, + }), + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeNumber, + formType: provider.ParameterFormTypeRadio, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeNumber, + formType: provider.ParameterFormTypeInput, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeNumber, + formType: provider.ParameterFormTypeSlider, + }), + // Boolean + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeBoolean, + formType: provider.ParameterFormTypeRadio, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeBoolean, + formType: provider.ParameterFormTypeSwitch, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeBoolean, + formType: provider.ParameterFormTypeCheckbox, + }), + // List(string) + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeListString, + formType: provider.ParameterFormTypeRadio, + }), + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeListString, + formType: provider.ParameterFormTypeMultiSelect, + customOptions: []string{"red", "blue", "green"}, + defValue: `["red", "blue"]`, + }), + expectSameFormType(formTypeCheck{ + options: false, + optionType: provider.OptionTypeListString, + formType: provider.ParameterFormTypeTagSelect, + }), + + // Some manual test cases + { + name: "list_string_bad_default", + config: formTypeCheck{ + formType: provider.ParameterFormTypeMultiSelect, + optionType: provider.OptionTypeListString, + customOptions: []string{"red", "blue", "green"}, + defValue: `["red", "yellow"]`, + styling: nil, + }, + expectError: regexp.MustCompile("is not a valid option"), + }, + } + + passed := t.Run("TabledTests", func(t *testing.T) { + // TabledCases runs through all the manual test cases + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + t.Parallel() + if _, ok := formTypesChecked[c.config.String()]; ok { + t.Log("Duplicated form type check, delete this extra test case") + t.Fatalf("form type %q already checked", c.config.String()) + } + + formTypesChecked[c.config.String()] = struct{}{} + formTypeTest(t, c) + }) + } + }) + + if !passed { + // Do not run additional tests and pollute the output + t.Log("Tests failed, will not run the assumed error cases") + return + } + + // AssumeErrorCases assumes any uncovered test will return an error. Not covered + // cases in the truth table are assumed to be invalid. So if the tests above + // cover all valid cases, this asserts all the invalid cases. + // + // This test consequentially ensures all valid cases are covered manually above. + t.Run("AssumeErrorCases", func(t *testing.T) { + // requiredChecks loops through all possible form_type and option_type + // combinations. + requiredChecks := make([]formTypeCheck, 0) + for _, ft := range append(provider.ParameterFormTypes(), "") { + for _, ot := range provider.OptionTypes() { + requiredChecks = append(requiredChecks, formTypeCheck{ + formType: ft, + optionType: ot, + options: false, + }) + requiredChecks = append(requiredChecks, formTypeCheck{ + formType: ft, + optionType: ot, + options: true, + }) + } + } + + for _, check := range requiredChecks { + if _, alreadyChecked := formTypesChecked[check.String()]; alreadyChecked { + continue + } + + ftName := check.formType + if ftName == "" { + ftName = "default" + } + fc := formTypeTestCase{ + name: fmt.Sprintf("%s_%s_%t", + ftName, + check.optionType, + check.options, + ), + config: check, + assert: paramAssert{}, + expectError: regexp.MustCompile("is not supported"), + } + + t.Run(fc.name, func(t *testing.T) { + t.Parallel() + + // This is just helpful log output to give the boilerplate + // to write the manual test. + tcText := fmt.Sprintf(` + expectSameFormType(%s, ezconfigOpts{ + Options: %t, + OptionType: %q, + FormType: %q, + }), + //`, "", check.options, check.optionType, check.formType) + + logDebugInfo := formTypeTest(t, fc) + if !logDebugInfo { + t.Logf("To construct this test case:\n%s", tcText) + } + }) + + } + }) +} + +// createTF converts a formTypeCheck into a terraform config string. +func createTF(paramName string, cfg formTypeCheck) (defaultValue string, tf string) { + options := cfg.customOptions + if cfg.options && len(cfg.customOptions) == 0 { + switch cfg.optionType { + case provider.OptionTypeString: + options = []string{"foo"} + defaultValue = "foo" + case provider.OptionTypeBoolean: + options = []string{"true", "false"} + defaultValue = "true" + case provider.OptionTypeNumber: + options = []string{"1"} + defaultValue = "1" + case provider.OptionTypeListString: + options = []string{`["red", "blue"]`} + defaultValue = `["red", "blue"]` + default: + panic(fmt.Sprintf("unknown option type %q when generating options", cfg.optionType)) + } + } + + if cfg.defValue == "" { + cfg.defValue = defaultValue + } + + var body strings.Builder + if cfg.defValue != "" { + body.WriteString(fmt.Sprintf("default = %q\n", cfg.defValue)) + } + if cfg.formType != "" { + body.WriteString(fmt.Sprintf("form_type = %q\n", cfg.formType)) + } + if cfg.optionType != "" { + body.WriteString(fmt.Sprintf("type = %q\n", cfg.optionType)) + } + if cfg.styling != nil { + body.WriteString(fmt.Sprintf("styling = %s\n", strconv.Quote(string(cfg.styling)))) + } + + for i, opt := range options { + body.WriteString("option {\n") + body.WriteString(fmt.Sprintf("name = \"val_%d\"\n", i)) + body.WriteString(fmt.Sprintf("value = %q\n", opt)) + body.WriteString("}\n") + } + + return cfg.defValue, fmt.Sprintf(` + provider "coder" { + } + data "coder_parameter" "%s" { + name = "%s" + %s + } + `, paramName, paramName, body.String()) +} + +func formTypeTest(t *testing.T, c formTypeTestCase) bool { + t.Helper() + const paramName = "test_param" + // logDebugInfo is just a guess used for logging. It's not important. It cannot + // determine for sure if the test passed because the terraform test runner is a + // black box. It does not indicate if the test passed or failed. Since this is + // just used for logging, this is good enough. + logDebugInfo := true + + def, tf := createTF(paramName, c.config) + checkFn := func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + key := strings.Join([]string{"data", "coder_parameter", paramName}, ".") + param := state.Modules[0].Resources[key] + + logDebugInfo = logDebugInfo && assert.Equal(t, def, param.Primary.Attributes["default"], "default value") + logDebugInfo = logDebugInfo && assert.Equal(t, string(c.assert.FormType), param.Primary.Attributes["form_type"], "form_type") + logDebugInfo = logDebugInfo && assert.Equal(t, string(c.assert.Type), param.Primary.Attributes["type"], "type") + logDebugInfo = logDebugInfo && assert.JSONEq(t, string(c.assert.Styling), param.Primary.Attributes["styling"], "styling") + + return nil + } + if c.expectError != nil { + checkFn = nil + } + + resource.Test(t, resource.TestCase{ + IsUnitTest: true, + ProviderFactories: coderFactory(), + Steps: []resource.TestStep{ + { + Config: tf, + Check: checkFn, + ExpectError: c.expectError, + }, + }, + }) + + if !logDebugInfo { + t.Logf("Terraform config:\n%s", tf) + } + return logDebugInfo +} diff --git a/provider/parameter.go b/provider/parameter.go index 1345f4d6..4eb8a282 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -50,7 +50,8 @@ type Parameter struct { Name string DisplayName string `mapstructure:"display_name"` Description string - Type string + Type OptionType + FormType ParameterFormType Mutable bool Default string Icon string @@ -86,6 +87,7 @@ func parameterDataSource() *schema.Resource { DisplayName interface{} Description interface{} Type interface{} + FormType interface{} Mutable interface{} Default interface{} Icon interface{} @@ -100,6 +102,7 @@ func parameterDataSource() *schema.Resource { DisplayName: rd.Get("display_name"), Description: rd.Get("description"), Type: rd.Get("type"), + FormType: rd.Get("form_type"), Mutable: rd.Get("mutable"), Default: rd.Get("default"), Icon: rd.Get("icon"), @@ -149,6 +152,20 @@ func parameterDataSource() *schema.Resource { } } + // Validate options + + // optionType might differ from parameter.Type. This is ok, and parameter.Type + // should be used for the value type, and optionType for options. + var optionType OptionType + optionType, parameter.FormType, err = ValidateFormType(parameter.Type, len(parameter.Option), parameter.FormType) + if err != nil { + return diag.FromErr(err) + } + // Set the form_type back in case the value was changed. + // Eg via a default. If a user does not specify, a default value + // is used and saved. + rd.Set("form_type", parameter.FormType) + if len(parameter.Option) > 0 { names := map[string]interface{}{} values := map[string]interface{}{} @@ -161,7 +178,7 @@ func parameterDataSource() *schema.Resource { if exists { return diag.Errorf("multiple options cannot have the same value %q", option.Value) } - err := valueIsType(parameter.Type, option.Value) + err := valueIsType(optionType, option.Value) if err != nil { return err } @@ -170,9 +187,36 @@ func parameterDataSource() *schema.Resource { } if parameter.Default != "" { - _, defaultIsValid := values[parameter.Default] - if !defaultIsValid { - return diag.Errorf("default value %q must be defined as one of options", parameter.Default) + if parameter.Type == OptionTypeListString && optionType == OptionTypeString { + // If the type is list(string) and optionType is string, we have + // to ensure all elements of the default exist as options. + var defaultValues []string + // TODO: We do this unmarshal in a few spots. It should be standardized. + err = json.Unmarshal([]byte(parameter.Default), &defaultValues) + if err != nil { + return diag.Errorf("default value %q is not a list of strings", parameter.Default) + } + + // missing is used to construct a more helpful error message + var missing []string + for _, defaultValue := range defaultValues { + _, defaultIsValid := values[defaultValue] + if !defaultIsValid { + missing = append(missing, defaultValue) + } + } + + if len(missing) > 0 { + return diag.Errorf( + "default value %q is not a valid option, values %q are missing from the option", + parameter.Default, strings.Join(missing, ", "), + ) + } + } else { + _, defaultIsValid := values[parameter.Default] + if !defaultIsValid { + return diag.Errorf("%q default value %q must be defined as one of options", parameter.FormType, parameter.Default) + } } } } @@ -203,9 +247,23 @@ func parameterDataSource() *schema.Resource { Type: schema.TypeString, Default: "string", Optional: true, - ValidateFunc: validation.StringInSlice([]string{"number", "string", "bool", "list(string)"}, false), + ValidateFunc: validation.StringInSlice(toStrings(OptionTypes()), false), Description: "The type of this parameter. Must be one of: `\"number\"`, `\"string\"`, `\"bool\"`, or `\"list(string)\"`.", }, + "form_type": { + Type: schema.TypeString, + Default: ParameterFormTypeDefault, + Optional: true, + ValidateFunc: validation.StringInSlice(toStrings(ParameterFormTypes()), false), + Description: fmt.Sprintf("The type of this parameter. Must be one of: [%s].", strings.Join(toStrings(ParameterFormTypes()), ", ")), + }, + "styling": { + Type: schema.TypeString, + Default: `{}`, + Description: "JSON encoded string containing the metadata for controlling the appearance of this parameter in the UI. " + + "This option is purely cosmetic and does not affect the function of the parameter in terraform.", + Optional: true, + }, "mutable": { Type: schema.TypeBool, Optional: true, @@ -375,25 +433,25 @@ func fixValidationResourceData(rawConfig cty.Value, validation interface{}) (int return vArr, nil } -func valueIsType(typ, value string) diag.Diagnostics { +func valueIsType(typ OptionType, value string) diag.Diagnostics { switch typ { - case "number": + case OptionTypeNumber: _, err := strconv.ParseFloat(value, 64) if err != nil { return diag.Errorf("%q is not a number", value) } - case "bool": + case OptionTypeBoolean: _, err := strconv.ParseBool(value) if err != nil { return diag.Errorf("%q is not a bool", value) } - case "list(string)": + case OptionTypeListString: var items []string err := json.Unmarshal([]byte(value), &items) if err != nil { return diag.Errorf("%q is not an array of strings", value) } - case "string": + case OptionTypeString: // Anything is a string! default: return diag.Errorf("invalid type %q", typ) @@ -401,8 +459,8 @@ func valueIsType(typ, value string) diag.Diagnostics { return nil } -func (v *Validation) Valid(typ, value string) error { - if typ != "number" { +func (v *Validation) Valid(typ OptionType, value string) error { + if typ != OptionTypeNumber { if !v.MinDisabled { return fmt.Errorf("a min cannot be specified for a %s type", typ) } @@ -413,16 +471,16 @@ func (v *Validation) Valid(typ, value string) error { return fmt.Errorf("monotonic validation can only be specified for number types, not %s types", typ) } } - if typ != "string" && v.Regex != "" { + if typ != OptionTypeString && v.Regex != "" { return fmt.Errorf("a regex cannot be specified for a %s type", typ) } switch typ { - case "bool": + case OptionTypeBoolean: if value != "true" && value != "false" { return fmt.Errorf(`boolean value can be either "true" or "false"`) } return nil - case "string": + case OptionTypeString: if v.Regex == "" { return nil } @@ -437,7 +495,7 @@ func (v *Validation) Valid(typ, value string) error { if !matched { return fmt.Errorf("%s (value %q does not match %q)", v.Error, value, regex) } - case "number": + case OptionTypeNumber: num, err := strconv.Atoi(value) if err != nil { return takeFirstError(v.errorRendered(value), fmt.Errorf("value %q is not a number", value)) @@ -451,7 +509,7 @@ func (v *Validation) Valid(typ, value string) error { if v.Monotonic != "" && v.Monotonic != ValidationMonotonicIncreasing && v.Monotonic != ValidationMonotonicDecreasing { return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing) } - case "list(string)": + case OptionTypeListString: var listOfStrings []string err := json.Unmarshal([]byte(value), &listOfStrings) if err != nil { diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 7bcea8fd..f817280e 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -27,6 +27,7 @@ func TestParameter(t *testing.T) { name = "region" display_name = "Region" type = "string" + form_type = "dropdown" description = <<-EOT # Select the machine image See the [registry](https://container.registry.blah/namespace) for options. @@ -56,6 +57,7 @@ func TestParameter(t *testing.T) { "name": "region", "display_name": "Region", "type": "string", + "form_type": "dropdown", "description": "# Select the machine image\nSee the [registry](https://container.registry.blah/namespace) for options.\n", "mutable": "true", "icon": "/icon/region.svg", @@ -137,6 +139,7 @@ func TestParameter(t *testing.T) { for key, expected := range map[string]string{ "name": "Region", "type": "number", + "form_type": "input", "validation.#": "1", "default": "2", "validation.0.min": "1", @@ -686,13 +689,13 @@ data "coder_parameter" "region" { func TestValueValidatesType(t *testing.T) { t.Parallel() for _, tc := range []struct { - Name, - Type, - Value, - Regex, - RegexError string - Min, - Max int + Name string + Type provider.OptionType + Value string + Regex string + RegexError string + Min int + Max int MinDisabled, MaxDisabled bool Monotonic string Error *regexp.Regexp From d90c1817de41ff9768ce7be861a66ea02773c2ee Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 9 Apr 2025 09:04:53 -0500 Subject: [PATCH 155/173] chore: change OptionType to alias for usage as string (#377) To be backwards compatible using this repo as a library, use a string alias. This allows using the 'type' as a `string` or the new enum. Since enum validation is quite weak in Go, this is baiscally functionally equvialent. --- provider/formtype.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/formtype.go b/provider/formtype.go index 48fbeed3..753f8945 100644 --- a/provider/formtype.go +++ b/provider/formtype.go @@ -13,7 +13,7 @@ import ( // // The value have to be string literals, as type constraint keywords are not // supported in providers. -type OptionType string +type OptionType = string const ( OptionTypeString OptionType = "string" From 53a68cd7496371d6f325f9c7bd8c6808069c4664 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Thu, 10 Apr 2025 11:52:25 +0200 Subject: [PATCH 156/173] feat: add the option to debug the coder terraform provider (#378) Setting the debug flag runs the provider as a standalone process and provides an environment variable that can be set for Terraform to use it. One can then attach a debugger to the provider process. --- main.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 2eaa5dc5..ef606a6d 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "flag" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" "github.com/coder/terraform-provider-coder/v2/provider" @@ -11,8 +13,15 @@ import ( //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs func main() { - servePprof() - plugin.Serve(&plugin.ServeOpts{ + debug := flag.Bool("debug", false, "Enable debug mode for the provider") + flag.Parse() + + opts := &plugin.ServeOpts{ + Debug: *debug, + ProviderAddr: "registry.terraform.io/coder/coder", ProviderFunc: provider.New, - }) + } + + servePprof() + plugin.Serve(opts) } From f66adaca2adfb6b19108200483855c4023fcc982 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 14 Apr 2025 09:05:16 -0500 Subject: [PATCH 157/173] chore: enhance parameter validation error messages (#379) * chore: implement validation in an exported function * chore: enhance parameter validation error messages --- provider/formtype.go | 28 +++++- provider/parameter.go | 197 +++++++++++++++++++++++++------------ provider/parameter_test.go | 4 +- 3 files changed, 159 insertions(+), 70 deletions(-) diff --git a/provider/formtype.go b/provider/formtype.go index 753f8945..75d32c46 100644 --- a/provider/formtype.go +++ b/provider/formtype.go @@ -115,9 +115,11 @@ var formTypeTruthTable = map[OptionType]map[bool][]ParameterFormType{ // The use case is when using multi-select. The options are 'string' and the // value is 'list(string)'. func ValidateFormType(paramType OptionType, optionCount int, specifiedFormType ParameterFormType) (OptionType, ParameterFormType, error) { - allowed, ok := formTypeTruthTable[paramType][optionCount > 0] + optionsExist := optionCount > 0 + allowed, ok := formTypeTruthTable[paramType][optionsExist] if !ok || len(allowed) == 0 { - return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", paramType) + // This error should really never be hit, as the provider sdk does an enum validation. + return paramType, specifiedFormType, xerrors.Errorf("\"type\" attribute=%q is not supported, choose one of %v", paramType, OptionTypes()) } if specifiedFormType == ParameterFormTypeDefault { @@ -126,7 +128,27 @@ func ValidateFormType(paramType OptionType, optionCount int, specifiedFormType P } if !slices.Contains(allowed, specifiedFormType) { - return paramType, specifiedFormType, xerrors.Errorf("value type %q is not supported for 'form_types'", specifiedFormType) + optionMsg := "" + opposite := formTypeTruthTable[paramType][!optionsExist] + + // This extra message tells a user if they are using a valid form_type + // for a 'type', but it is invalid because options do/do-not exist. + // It serves as a more helpful error message. + // + // Eg: form_type=slider is valid for type=number, but invalid if options exist. + // And this error message is more accurate than just saying "form_type=slider is + // not valid for type=number". + if slices.Contains(opposite, specifiedFormType) { + if optionsExist { + optionMsg = " when options exist" + } else { + optionMsg = " when options do not exist" + } + } + return paramType, specifiedFormType, + xerrors.Errorf("\"form_type\" attribute=%q is not supported for \"type\"=%q%s, choose one of %v", + specifiedFormType, paramType, + optionMsg, toStrings(allowed)) } // This is the only current special case. If 'multi-select' is selected, the type diff --git a/provider/parameter.go b/provider/parameter.go index 4eb8a282..2f7dc662 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -124,7 +124,7 @@ func parameterDataSource() *schema.Resource { } var value string if parameter.Default != "" { - err := valueIsType(parameter.Type, parameter.Default) + err := valueIsType(parameter.Type, parameter.Default, cty.Path{cty.GetAttrStep{Name: "default"}}) if err != nil { return err } @@ -144,6 +144,8 @@ func parameterDataSource() *schema.Resource { return diag.Errorf("ephemeral parameter requires the default property") } + // TODO: Should we move this into the Valid() function on + // Parameter? if len(parameter.Validation) == 1 { validation := ¶meter.Validation[0] err = validation.Valid(parameter.Type, value) @@ -153,73 +155,27 @@ func parameterDataSource() *schema.Resource { } // Validate options - - // optionType might differ from parameter.Type. This is ok, and parameter.Type - // should be used for the value type, and optionType for options. - var optionType OptionType - optionType, parameter.FormType, err = ValidateFormType(parameter.Type, len(parameter.Option), parameter.FormType) + _, parameter.FormType, err = ValidateFormType(parameter.Type, len(parameter.Option), parameter.FormType) if err != nil { - return diag.FromErr(err) + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "Invalid form_type for parameter", + Detail: err.Error(), + AttributePath: cty.Path{cty.GetAttrStep{Name: "form_type"}}, + }, + } } // Set the form_type back in case the value was changed. // Eg via a default. If a user does not specify, a default value // is used and saved. rd.Set("form_type", parameter.FormType) - if len(parameter.Option) > 0 { - names := map[string]interface{}{} - values := map[string]interface{}{} - for _, option := range parameter.Option { - _, exists := names[option.Name] - if exists { - return diag.Errorf("multiple options cannot have the same name %q", option.Name) - } - _, exists = values[option.Value] - if exists { - return diag.Errorf("multiple options cannot have the same value %q", option.Value) - } - err := valueIsType(optionType, option.Value) - if err != nil { - return err - } - values[option.Value] = nil - names[option.Name] = nil - } - - if parameter.Default != "" { - if parameter.Type == OptionTypeListString && optionType == OptionTypeString { - // If the type is list(string) and optionType is string, we have - // to ensure all elements of the default exist as options. - var defaultValues []string - // TODO: We do this unmarshal in a few spots. It should be standardized. - err = json.Unmarshal([]byte(parameter.Default), &defaultValues) - if err != nil { - return diag.Errorf("default value %q is not a list of strings", parameter.Default) - } - - // missing is used to construct a more helpful error message - var missing []string - for _, defaultValue := range defaultValues { - _, defaultIsValid := values[defaultValue] - if !defaultIsValid { - missing = append(missing, defaultValue) - } - } - - if len(missing) > 0 { - return diag.Errorf( - "default value %q is not a valid option, values %q are missing from the option", - parameter.Default, strings.Join(missing, ", "), - ) - } - } else { - _, defaultIsValid := values[parameter.Default] - if !defaultIsValid { - return diag.Errorf("%q default value %q must be defined as one of options", parameter.FormType, parameter.Default) - } - } - } + diags := parameter.Valid() + if diags.HasError() { + return diags } + return nil }, Schema: map[string]*schema.Schema{ @@ -433,7 +389,7 @@ func fixValidationResourceData(rawConfig cty.Value, validation interface{}) (int return vArr, nil } -func valueIsType(typ OptionType, value string) diag.Diagnostics { +func valueIsType(typ OptionType, value string, attrPath cty.Path) diag.Diagnostics { switch typ { case OptionTypeNumber: _, err := strconv.ParseFloat(value, 64) @@ -446,10 +402,9 @@ func valueIsType(typ OptionType, value string) diag.Diagnostics { return diag.Errorf("%q is not a bool", value) } case OptionTypeListString: - var items []string - err := json.Unmarshal([]byte(value), &items) - if err != nil { - return diag.Errorf("%q is not an array of strings", value) + _, diags := valueIsListString(value, attrPath) + if diags.HasError() { + return diags } case OptionTypeString: // Anything is a string! @@ -459,6 +414,102 @@ func valueIsType(typ OptionType, value string) diag.Diagnostics { return nil } +func (v *Parameter) Valid() diag.Diagnostics { + // optionType might differ from parameter.Type. This is ok, and parameter.Type + // should be used for the value type, and optionType for options. + optionType, _, err := ValidateFormType(v.Type, len(v.Option), v.FormType) + if err != nil { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "Invalid form_type for parameter", + Detail: err.Error(), + AttributePath: cty.Path{cty.GetAttrStep{Name: "form_type"}}, + }, + } + } + + optionNames := map[string]any{} + optionValues := map[string]any{} + if len(v.Option) > 0 { + for _, option := range v.Option { + _, exists := optionNames[option.Name] + if exists { + return diag.Diagnostics{{ + Severity: diag.Error, + Summary: "Option names must be unique.", + Detail: fmt.Sprintf("multiple options found with the same name %q", option.Name), + }, + } + } + _, exists = optionValues[option.Value] + if exists { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "Option values must be unique.", + Detail: fmt.Sprintf("multiple options found with the same value %q", option.Value), + }, + } + } + diags := valueIsType(optionType, option.Value, cty.Path{}) + if diags.HasError() { + return diags + } + optionValues[option.Value] = nil + optionNames[option.Name] = nil + } + } + + if v.Default != "" && len(v.Option) > 0 { + if v.Type == OptionTypeListString && optionType == OptionTypeString { + // If the type is list(string) and optionType is string, we have + // to ensure all elements of the default exist as options. + defaultValues, diags := valueIsListString(v.Default, cty.Path{cty.GetAttrStep{Name: "default"}}) + if diags.HasError() { + return diags + } + + // missing is used to construct a more helpful error message + var missing []string + for _, defaultValue := range defaultValues { + _, defaultIsValid := optionValues[defaultValue] + if !defaultIsValid { + missing = append(missing, defaultValue) + } + } + + if len(missing) > 0 { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "Default values must be a valid option", + Detail: fmt.Sprintf( + "default value %q is not a valid option, values %q are missing from the options", + v.Default, strings.Join(missing, ", "), + ), + AttributePath: cty.Path{cty.GetAttrStep{Name: "default"}}, + }, + } + } + } else { + _, defaultIsValid := optionValues[v.Default] + if !defaultIsValid { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "Default value must be a valid option", + Detail: fmt.Sprintf("the value %q must be defined as one of options", v.Default), + AttributePath: cty.Path{cty.GetAttrStep{Name: "default"}}, + }, + } + } + } + } + + return nil +} + func (v *Validation) Valid(typ OptionType, value string) error { if typ != OptionTypeNumber { if !v.MinDisabled { @@ -519,6 +570,22 @@ func (v *Validation) Valid(typ OptionType, value string) error { return nil } +func valueIsListString(value string, path cty.Path) ([]string, diag.Diagnostics) { + var items []string + err := json.Unmarshal([]byte(value), &items) + if err != nil { + return nil, diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "When using list(string) type, value must be a json encoded list of strings", + Detail: fmt.Sprintf("value %q is not a valid list of strings", value), + AttributePath: path, + }, + } + } + return items, nil +} + // ParameterEnvironmentVariable returns the environment variable to specify for // a parameter by it's name. It's hashed because spaces and special characters // can be used in parameter names that may not be valid in env vars. diff --git a/provider/parameter_test.go b/provider/parameter_test.go index f817280e..4b52d943 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -291,7 +291,7 @@ func TestParameter(t *testing.T) { } } `, - ExpectError: regexp.MustCompile("cannot have the same name"), + ExpectError: regexp.MustCompile("Option names must be unique"), }, { Name: "DuplicateOptionValue", Config: ` @@ -308,7 +308,7 @@ func TestParameter(t *testing.T) { } } `, - ExpectError: regexp.MustCompile("cannot have the same value"), + ExpectError: regexp.MustCompile("Option values must be unique"), }, { Name: "RequiredParameterNoDefault", Config: ` From e40c9b9278ad0a7574bbeb067e2119f850b0df5c Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 15 Apr 2025 10:54:10 +0100 Subject: [PATCH 158/173] chore: update to go 1.24.2 (#382) Co-authored-by: Danny Kopping --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 02ea7137..993ba093 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/coder/terraform-provider-coder/v2 -go 1.22.9 +go 1.24.2 require ( github.com/docker/docker v26.1.5+incompatible From e51ae3aff8c4c0c3c0559841fabb59eafea1f86a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 10:59:50 +0100 Subject: [PATCH 159/173] build(deps): Bump golang.org/x/crypto from 0.33.0 to 0.35.0 (#380) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.33.0 to 0.35.0. - [Commits](https://github.com/golang/crypto/compare/v0.33.0...v0.35.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.35.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 993ba093..cb415c2b 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/otel/trace v1.31.0 // indirect - golang.org/x/crypto v0.33.0 // indirect + golang.org/x/crypto v0.35.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.30.0 // indirect diff --git a/go.sum b/go.sum index 2b5ad9c5..870d770d 100644 --- a/go.sum +++ b/go.sum @@ -225,8 +225,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= From c86bb5c3ddcd0735fefe644b264c04f9ecafbd4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:02:58 +0100 Subject: [PATCH 160/173] build(deps): Bump golang.org/x/net from 0.34.0 to 0.38.0 (#383) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.38.0. - [Commits](https://github.com/golang/net/compare/v0.34.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.38.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index cb415c2b..848423f4 100644 --- a/go.mod +++ b/go.mod @@ -79,11 +79,11 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/otel/trace v1.31.0 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index 870d770d..77c61771 100644 --- a/go.sum +++ b/go.sum @@ -225,8 +225,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -240,15 +240,15 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL 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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -263,8 +263,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -272,8 +272,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From f871a43ee9a2615a195da72821148a2045ff0d6d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 23 Apr 2025 08:44:20 -0500 Subject: [PATCH 161/173] test: rbac role test assertion to handle site wide roles (#385) Site wide roles have empty string org_ids --- integration/integration_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integration/integration_test.go b/integration/integration_test.go index 9803aa41..a5019635 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -181,7 +181,8 @@ func TestIntegration(t *testing.T) { "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, "workspace_owner.login_type": `password`, - "workspace_owner.rbac_roles": `(?is)\[(\{"name":"[a-z0-9-:]+","org_id":"[a-f0-9-]+"\},?)+\]`, + // org_id will either be a uuid or an empty string for site wide roles. + "workspace_owner.rbac_roles": `(?is)\[(\{"name":"[a-z0-9-:]+","org_id":"[a-f0-9-]*"\},?)+\]`, }, }, { From ac2f9bf28b20a387661cf9f45444a5ceda0dc689 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 30 Apr 2025 14:30:36 -0500 Subject: [PATCH 162/173] test: unit test to document validation behavior of parameters (#387) Documenting validation behavior with a unit test --- provider/parameter_test.go | 232 +++++++++++++++++++++++++++ provider/testdata/parameter_table.md | 70 ++++++++ 2 files changed, 302 insertions(+) create mode 100644 provider/testdata/parameter_table.md diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 4b52d943..37a46796 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -2,7 +2,9 @@ package provider_test import ( "fmt" + "os" "regexp" + "strconv" "strings" "testing" @@ -686,6 +688,217 @@ data "coder_parameter" "region" { } } +// TestParameterValidationEnforcement tests various parameter states and the +// validation enforcement that should be applied to them. The table is described +// by a markdown table. This is done so that the test cases can be more easily +// edited and read. +// +// Copy and paste the table to https://www.tablesgenerator.com/markdown_tables for easier editing +// +//nolint:paralleltest,tparallel // Parameters load values from env vars +func TestParameterValidationEnforcement(t *testing.T) { + // Some interesting observations: + // - Validation logic does not apply to the value of 'options' + // - [NumDefInvOpt] So an invalid option can be present and selected, but would fail + // - Validation logic does not apply to the default if a value is given + // - [NumIns/DefInv] So the default can be invalid if an input value is valid. + // The value is therefore not really optional, but it is marked as such. + // - [NumInsNotOptsVal | NumsInsNotOpts] values do not need to be in the option set? + table, err := os.ReadFile("testdata/parameter_table.md") + require.NoError(t, err) + + type row struct { + Name string + Types []string + InputValue string + Default string + Options []string + Validation *provider.Validation + OutputValue string + Optional bool + Error *regexp.Regexp + } + + rows := make([]row, 0) + lines := strings.Split(string(table), "\n") + validMinMax := regexp.MustCompile("^[0-9]*-[0-9]*$") + for _, line := range lines[2:] { + columns := strings.Split(line, "|") + columns = columns[1 : len(columns)-1] + for i := range columns { + // Trim the whitespace from all columns + columns[i] = strings.TrimSpace(columns[i]) + } + + if columns[0] == "" { + continue // Skip rows with empty names + } + + optional, err := strconv.ParseBool(columns[8]) + if columns[8] != "" { + // Value does not matter if not specified + require.NoError(t, err) + } + + var rerr *regexp.Regexp + if columns[9] != "" { + rerr, err = regexp.Compile(columns[9]) + if err != nil { + t.Fatalf("failed to parse error column %q: %v", columns[9], err) + } + } + var options []string + if columns[4] != "" { + options = strings.Split(columns[4], ",") + } + + var validation *provider.Validation + if columns[5] != "" { + // Min-Max validation should look like: + // 1-10 :: min=1, max=10 + // -10 :: max=10 + // 1- :: min=1 + if validMinMax.MatchString(columns[5]) { + parts := strings.Split(columns[5], "-") + min, _ := strconv.ParseInt(parts[0], 10, 64) + max, _ := strconv.ParseInt(parts[1], 10, 64) + validation = &provider.Validation{ + Min: int(min), + MinDisabled: parts[0] == "", + Max: int(max), + MaxDisabled: parts[1] == "", + Monotonic: "", + Regex: "", + Error: "{min} < {value} < {max}", + } + } else { + validation = &provider.Validation{ + Min: 0, + MinDisabled: true, + Max: 0, + MaxDisabled: true, + Monotonic: "", + Regex: columns[5], + Error: "regex error", + } + } + } + + rows = append(rows, row{ + Name: columns[0], + Types: strings.Split(columns[1], ","), + InputValue: columns[2], + Default: columns[3], + Options: options, + Validation: validation, + OutputValue: columns[7], + Optional: optional, + Error: rerr, + }) + } + + stringLiteral := func(s string) string { + if s == "" { + return `""` + } + return fmt.Sprintf("%q", s) + } + + for rowIndex, row := range rows { + for _, rt := range row.Types { + //nolint:paralleltest,tparallel // Parameters load values from env vars + t.Run(fmt.Sprintf("%d|%s:%s", rowIndex, row.Name, rt), func(t *testing.T) { + if row.InputValue != "" { + t.Setenv(provider.ParameterEnvironmentVariable("parameter"), row.InputValue) + } + + if row.Error != nil { + if row.OutputValue != "" { + t.Errorf("output value %q should not be set if error is set", row.OutputValue) + } + } + + var cfg strings.Builder + cfg.WriteString("data \"coder_parameter\" \"parameter\" {\n") + cfg.WriteString("\tname = \"parameter\"\n") + if rt == "multi-select" || rt == "tag-select" { + cfg.WriteString(fmt.Sprintf("\ttype = \"%s\"\n", "list(string)")) + cfg.WriteString(fmt.Sprintf("\tform_type = \"%s\"\n", rt)) + } else { + cfg.WriteString(fmt.Sprintf("\ttype = \"%s\"\n", rt)) + } + if row.Default != "" { + cfg.WriteString(fmt.Sprintf("\tdefault = %s\n", stringLiteral(row.Default))) + } + + for _, opt := range row.Options { + cfg.WriteString("\toption {\n") + cfg.WriteString(fmt.Sprintf("\t\tname = %s\n", stringLiteral(opt))) + cfg.WriteString(fmt.Sprintf("\t\tvalue = %s\n", stringLiteral(opt))) + cfg.WriteString("\t}\n") + } + + if row.Validation != nil { + cfg.WriteString("\tvalidation {\n") + if !row.Validation.MinDisabled { + cfg.WriteString(fmt.Sprintf("\t\tmin = %d\n", row.Validation.Min)) + } + if !row.Validation.MaxDisabled { + cfg.WriteString(fmt.Sprintf("\t\tmax = %d\n", row.Validation.Max)) + } + if row.Validation.Monotonic != "" { + cfg.WriteString(fmt.Sprintf("\t\tmonotonic = \"%s\"\n", row.Validation.Monotonic)) + } + if row.Validation.Regex != "" { + cfg.WriteString(fmt.Sprintf("\t\tregex = %q\n", row.Validation.Regex)) + } + cfg.WriteString(fmt.Sprintf("\t\terror = %q\n", row.Validation.Error)) + cfg.WriteString("\t}\n") + } + + cfg.WriteString("}\n") + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: cfg.String(), + ExpectError: row.Error, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + param := state.Modules[0].Resources["data.coder_parameter.parameter"] + require.NotNil(t, param) + + if row.Default == "" { + _, ok := param.Primary.Attributes["default"] + require.False(t, ok, "default should not be set") + } else { + require.Equal(t, strings.Trim(row.Default, `"`), param.Primary.Attributes["default"]) + } + + if row.OutputValue == "" { + _, ok := param.Primary.Attributes["value"] + require.False(t, ok, "output value should not be set") + } else { + require.Equal(t, strings.Trim(row.OutputValue, `"`), param.Primary.Attributes["value"]) + } + + for key, expected := range map[string]string{ + "optional": strconv.FormatBool(row.Optional), + } { + require.Equal(t, expected, param.Primary.Attributes[key], "optional") + } + + return nil + }, + }}, + }) + }) + } + } +} + func TestValueValidatesType(t *testing.T) { t.Parallel() for _, tc := range []struct { @@ -798,6 +1011,25 @@ func TestValueValidatesType(t *testing.T) { Value: `[]`, MinDisabled: true, MaxDisabled: true, + }, { + Name: "ValidListOfStrings", + Type: "list(string)", + Value: `["first","second","third"]`, + MinDisabled: true, + MaxDisabled: true, + }, { + Name: "InvalidListOfStrings", + Type: "list(string)", + Value: `["first","second","third"`, + MinDisabled: true, + MaxDisabled: true, + Error: regexp.MustCompile("is not valid list of strings"), + }, { + Name: "EmptyListOfStrings", + Type: "list(string)", + Value: `[]`, + MinDisabled: true, + MaxDisabled: true, }} { tc := tc t.Run(tc.Name, func(t *testing.T) { diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md new file mode 100644 index 00000000..4c9ee458 --- /dev/null +++ b/provider/testdata/parameter_table.md @@ -0,0 +1,70 @@ +| Name | Type | Input | Default | Options | Validation | -> | Output | Optional | Error | +|----------------------|---------------|-----------|---------|-------------------|------------|----|--------|----------|--------------| +| | Empty Vals | | | | | | | | | +| Empty | string,number | | | | | | "" | false | | +| EmptyList | list(string) | | | | | | "" | false | | +| EmptyMulti | tag-select | | | | | | "" | false | | +| EmptyOpts | string,number | | | 1,2,3 | | | "" | false | | +| EmptyRegex | string | | | | world | | | | regex error | +| EmptyMin | number | | | | 1-10 | | | | 1 < < 10 | +| EmptyMinOpt | number | | | 1,2,3 | 2-5 | | | | 2 < < 5 | +| EmptyRegexOpt | string | | | "hello","goodbye" | goodbye | | | | regex error | +| EmptyRegexOk | string | | | | .* | | "" | false | | +| | | | | | | | | | | +| | Default Set | No inputs | | | | | | | | +| NumDef | number | | 5 | | | | 5 | true | | +| NumDefVal | number | | 5 | | 3-7 | | 5 | true | | +| NumDefInv | number | | 5 | | 10- | | | | 10 < 5 < 0 | +| NumDefOpts | number | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | +| NumDefNotOpts | number | | 5 | 1,3,7,9 | 2-6 | | | | valid option | +| NumDefInvOpt | number | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | +| | | | | | | | | | | +| StrDef | string | | hello | | | | hello | true | | +| StrDefInv | string | | hello | | world | | | | regex error | +| StrDefOpts | string | | a | a,b,c | | | a | true | | +| StrDefNotOpts | string | | a | b,c,d | | | | | valid option | +| StrDefValOpts | string | | a | a,b,c,d,e,f | [a-c] | | a | true | | +| StrDefInvOpt | string | | d | a,b,c,d,e,f | [a-c] | | | | regex error | +| | | | | | | | | | | +| LStrDef | list(string) | | ["a"] | | | | ["a"] | true | | +| LStrDefOpts | list(string) | | ["a"] | ["a"], ["b"] | | | ["a"] | true | | +| LStrDefNotOpts | list(string) | | ["a"] | ["b"], ["c"] | | | | | valid option | +| | | | | | | | | | | +| MulDef | tag-select | | ["a"] | | | | ["a"] | true | | +| MulDefOpts | multi-select | | ["a"] | a,b | | | ["a"] | true | | +| MulDefNotOpts | multi-select | | ["a"] | b,c | | | | | valid option | +| | | | | | | | | | | +| | Input Vals | | | | | | | | | +| NumIns | number | 3 | | | | | 3 | false | | +| NumInsDef | number | 3 | 5 | | | | 3 | true | | +| NumIns/DefInv | number | 3 | 5 | | 1-3 | | 3 | true | | +| NumIns=DefInv | number | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | +| NumInsOpts | number | 3 | 5 | 1,2,3,4,5 | 1-3 | | 3 | true | | +| NumInsNotOptsVal | number | 3 | 5 | 1,2,4,5 | 1-3 | | 3 | true | | +| NumInsNotOptsInv | number | 3 | 5 | 1,2,4,5 | 1-2 | | | true | 1 < 3 < 2 | +| NumInsNotOpts | number | 3 | 5 | 1,2,4,5 | | | 3 | true | | +| NumInsNotOpts/NoDef | number | 3 | | 1,2,4,5 | | | 3 | false | | +| | | | | | | | | | | +| StrIns | string | c | | | | | c | false | | +| StrInsDef | string | c | e | | | | c | true | | +| StrIns/DefInv | string | c | e | | [a-c] | | c | true | | +| StrIns=DefInv | string | e | e | | [a-c] | | | | regex error | +| StrInsOpts | string | c | e | a,b,c,d,e | [a-c] | | c | true | | +| StrInsNotOptsVal | string | c | e | a,b,d,e | [a-c] | | c | true | | +| StrInsNotOptsInv | string | c | e | a,b,d,e | [a-b] | | | | regex error | +| StrInsNotOpts | string | c | e | a,b,d,e | | | c | true | | +| StrInsNotOpts/NoDef | string | c | | a,b,d,e | | | c | false | | +| StrInsBadVal | string | c | | a,b,c,d,e | 1-10 | | | | min cannot | +| | | | | | | | | | | +| | list(string) | | | | | | | | | +| LStrIns | list(string) | ["c"] | | | | | ["c"] | false | | +| LStrInsDef | list(string) | ["c"] | ["e"] | | | | ["c"] | true | | +| LStrIns/DefInv | list(string) | ["c"] | ["e"] | | [a-c] | | | | regex cannot | +| LStrInsOpts | list(string) | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | +| LStrInsNotOpts | list(string) | ["c"] | ["e"] | ["d"],["e"] | | | ["c"] | true | | +| LStrInsNotOpts/NoDef | list(string) | ["c"] | | ["d"],["e"] | | | ["c"] | false | | +| | | | | | | | | | | +| MulInsOpts | multi-select | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | +| MulInsNotOpts | multi-select | ["c"] | ["e"] | d,e | | | ["c"] | true | | +| MulInsNotOpts/NoDef | multi-select | ["c"] | | d,e | | | ["c"] | false | | +| MulInsInvOpts | multi-select | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file From 4e7da25b24d24b43a0540296a2c50b80002b722a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 30 Apr 2025 16:30:22 -0500 Subject: [PATCH 163/173] test: add more validation test cases (#388) Some of these cases you would expect it to be an error, but the validation passes --- provider/parameter_test.go | 3 +++ provider/testdata/parameter_table.md | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 37a46796..32877c2b 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -704,6 +704,9 @@ func TestParameterValidationEnforcement(t *testing.T) { // - [NumIns/DefInv] So the default can be invalid if an input value is valid. // The value is therefore not really optional, but it is marked as such. // - [NumInsNotOptsVal | NumsInsNotOpts] values do not need to be in the option set? + // - [NumInsNotNum] number params do not require the value to be a number + // - [LStrInsNotList] list(string) do not require the value to be a list(string) + // - Same with [MulInsNotListOpts] table, err := os.ReadFile("testdata/parameter_table.md") require.NoError(t, err) diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md index 4c9ee458..f7645efa 100644 --- a/provider/testdata/parameter_table.md +++ b/provider/testdata/parameter_table.md @@ -2,7 +2,9 @@ |----------------------|---------------|-----------|---------|-------------------|------------|----|--------|----------|--------------| | | Empty Vals | | | | | | | | | | Empty | string,number | | | | | | "" | false | | +| EmptyDupeOps | string,number | | | 1,1,1 | | | | | unique | | EmptyList | list(string) | | | | | | "" | false | | +| EmptyListDupeOpts | list(string) | | | ["a"],["a"] | | | | | unique | | EmptyMulti | tag-select | | | | | | "" | false | | | EmptyOpts | string,number | | | 1,2,3 | | | "" | false | | | EmptyRegex | string | | | | world | | | | regex error | @@ -18,6 +20,8 @@ | NumDefOpts | number | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | | NumDefNotOpts | number | | 5 | 1,3,7,9 | 2-6 | | | | valid option | | NumDefInvOpt | number | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | +| NumDefNotNum | number | | a | | | | | | a number | +| NumDefOptsNotNum | number | | 1 | 1,a,2 | | | | | a number | | | | | | | | | | | | | StrDef | string | | hello | | | | hello | true | | | StrDefInv | string | | hello | | world | | | | regex error | @@ -36,6 +40,8 @@ | | | | | | | | | | | | | Input Vals | | | | | | | | | | NumIns | number | 3 | | | | | 3 | false | | +| NumInsNotNum | number | a | | | | | a | false | | +| NumInsNotNumInv | number | a | | | 1-3 | | | | 1 < a < 3 | | NumInsDef | number | 3 | 5 | | | | 3 | true | | | NumIns/DefInv | number | 3 | 5 | | 1-3 | | 3 | true | | | NumIns=DefInv | number | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | @@ -46,6 +52,7 @@ | NumInsNotOpts/NoDef | number | 3 | | 1,2,4,5 | | | 3 | false | | | | | | | | | | | | | | StrIns | string | c | | | | | c | false | | +| StrInsDupeOpts | string | c | | a,b,c,c | | | | | unique | | StrInsDef | string | c | e | | | | c | true | | | StrIns/DefInv | string | c | e | | [a-c] | | c | true | | | StrIns=DefInv | string | e | e | | [a-c] | | | | regex error | @@ -58,6 +65,7 @@ | | | | | | | | | | | | | list(string) | | | | | | | | | | LStrIns | list(string) | ["c"] | | | | | ["c"] | false | | +| LStrInsNotList | list(string) | c | | | | | c | false | | | LStrInsDef | list(string) | ["c"] | ["e"] | | | | ["c"] | true | | | LStrIns/DefInv | list(string) | ["c"] | ["e"] | | [a-c] | | | | regex cannot | | LStrInsOpts | list(string) | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | @@ -65,6 +73,7 @@ | LStrInsNotOpts/NoDef | list(string) | ["c"] | | ["d"],["e"] | | | ["c"] | false | | | | | | | | | | | | | | MulInsOpts | multi-select | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | +| MulInsNotListOpts | multi-select | c | ["e"] | c,d,e | | | c | true | | | MulInsNotOpts | multi-select | ["c"] | ["e"] | d,e | | | ["c"] | true | | | MulInsNotOpts/NoDef | multi-select | ["c"] | | d,e | | | ["c"] | false | | | MulInsInvOpts | multi-select | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file From 5648efbf6db0e02bd7cf79386650ade6cf923681 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Fri, 2 May 2025 08:57:05 +0200 Subject: [PATCH 164/173] feat: reuse agent tokens when a prebuilt agent reinitializes (#374) * feat: allow presets to define prebuilds * document prebuild parameters * remove todo * make gen * feat: reuse agent tokens when a prebuilt agent reinitializes * WIP: get agent.go ready to be merged with support for prebuilds * fix: ensure the agent token is reused for prebuilds * lint and make gen * simplify function * test: rbac role test assertion to handle site wide roles Site wide roles have empty string org_ids --------- Co-authored-by: Steven Masley --- go.mod | 2 +- provider/agent.go | 51 ++++++++++++++++++++++++++++++++++++++----- provider/workspace.go | 28 +++++++++++++++++++----- 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 848423f4..2d3db5d0 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/docker/docker v26.1.5+incompatible github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 + github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 github.com/masterminds/semver v1.5.0 github.com/mitchellh/mapstructure v1.5.0 @@ -50,7 +51,6 @@ require ( github.com/hashicorp/terraform-exec v0.22.0 // indirect github.com/hashicorp/terraform-json v0.24.0 // indirect github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.4 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect diff --git a/provider/agent.go b/provider/agent.go index 3ddae235..ad264030 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -2,6 +2,8 @@ package provider import ( "context" + "crypto/sha256" + "encoding/hex" "fmt" "path/filepath" "reflect" @@ -9,6 +11,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -22,10 +25,12 @@ func agentResource() *schema.Resource { SchemaVersion: 1, Description: "Use this resource to associate an agent.", - CreateContext: func(_ context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { - // This should be a real authentication token! - resourceData.SetId(uuid.NewString()) - err := resourceData.Set("token", uuid.NewString()) + CreateContext: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { + agentID := uuid.NewString() + resourceData.SetId(agentID) + + token := agentAuthToken(ctx, "") + err := resourceData.Set("token", token) if err != nil { return diag.FromErr(err) } @@ -48,10 +53,12 @@ func agentResource() *schema.Resource { return updateInitScript(resourceData, i) }, ReadWithoutTimeout: func(ctx context.Context, resourceData *schema.ResourceData, i interface{}) diag.Diagnostics { - err := resourceData.Set("token", uuid.NewString()) + token := agentAuthToken(ctx, "") + err := resourceData.Set("token", token) if err != nil { return diag.FromErr(err) } + if _, ok := resourceData.GetOk("display_apps"); !ok { err = resourceData.Set("display_apps", []interface{}{ map[string]bool{ @@ -469,3 +476,37 @@ func updateInitScript(resourceData *schema.ResourceData, i interface{}) diag.Dia } return nil } + +func agentAuthToken(ctx context.Context, agentID string) string { + existingToken := helpers.OptionalEnv(RunningAgentTokenEnvironmentVariable(agentID)) + if existingToken == "" { + // Most of the time, we will generate a new token for the agent. + // In the case of a prebuilt workspace being claimed, we will override with + // an existing token provided below. + token := uuid.NewString() + return token + } + + // An existing token was provided for this agent. That means that this + // is a prebuilt workspace in the process of being claimed. + // We should reuse the token. + tflog.Info(ctx, "using provided agent token for prebuild", map[string]interface{}{ + "agent_id": agentID, + }) + return existingToken +} + +// RunningAgentTokenEnvironmentVariable returns the name of an environment variable +// that contains the token to use for the running agent. This is used for prebuilds, +// where we want to reuse the same token for the next iteration of a workspace agent +// before and after the workspace was claimed by a user. +// +// By reusing an existing token, we can avoid the need to change a value that may have been +// used immutably. Thus, allowing us to avoid reprovisioning resources that may take a long time +// to replace. +// +// agentID is unused for now, but will be used as soon as we support multiple agents. +func RunningAgentTokenEnvironmentVariable(agentID string) string { + sum := sha256.Sum256([]byte(agentID)) + return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN_" + hex.EncodeToString(sum[:]) +} diff --git a/provider/workspace.go b/provider/workspace.go index 5ddd3ee8..c477fad6 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -27,13 +27,13 @@ func workspaceDataSource() *schema.Resource { } _ = rd.Set("start_count", count) - prebuild := helpers.OptionalEnv(IsPrebuildEnvironmentVariable()) - prebuildCount := 0 - if prebuild == "true" { - prebuildCount = 1 + if isPrebuiltWorkspace() { + _ = rd.Set("prebuild_count", 1) _ = rd.Set("is_prebuild", true) + } else { + _ = rd.Set("prebuild_count", 0) + _ = rd.Set("is_prebuild", false) } - _ = rd.Set("prebuild_count", prebuildCount) name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) @@ -140,6 +140,24 @@ func workspaceDataSource() *schema.Resource { } } +// isPrebuiltWorkspace returns true if the workspace is an unclaimed prebuilt workspace. +func isPrebuiltWorkspace() bool { + return helpers.OptionalEnv(IsPrebuildEnvironmentVariable()) == "true" +} + +// IsPrebuildEnvironmentVariable returns the name of the environment variable that +// indicates whether the workspace is an unclaimed prebuilt workspace. +// +// Knowing whether the workspace is an unclaimed prebuilt workspace allows template +// authors to conditionally execute code in the template based on whether the workspace +// has been assigned to a user or not. This allows identity specific configuration to +// be applied only after the workspace is claimed, while the rest of the workspace can +// be pre-configured. +// +// The value of this environment variable should be set to "true" if the workspace is prebuilt +// and it has not yet been claimed by a user. Any other values, including "false" +// and "" will be interpreted to mean that the workspace is not prebuilt, or was +// prebuilt but has since been claimed by a user. func IsPrebuildEnvironmentVariable() string { return "CODER_WORKSPACE_IS_PREBUILD" } From 21147bf3e4f814ce804be47204501d06740fa7dd Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 2 May 2025 10:08:37 -0500 Subject: [PATCH 165/173] test: fix concurrent map write of TestValidateFormType (#390) --- provider/formtype_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/provider/formtype_test.go b/provider/formtype_test.go index 599c2e41..eaf7b587 100644 --- a/provider/formtype_test.go +++ b/provider/formtype_test.go @@ -6,6 +6,7 @@ import ( "regexp" "strconv" "strings" + "sync" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -53,7 +54,7 @@ func TestValidateFormType(t *testing.T) { // formTypesChecked keeps track of all checks run. It will be used to // ensure all combinations of form_type and option_type are tested. // All untested options are assumed to throw an error. - formTypesChecked := make(map[string]struct{}) + var formTypesChecked sync.Map expectType := func(expected provider.ParameterFormType, opts formTypeCheck) formTypeTestCase { ftname := opts.formType @@ -240,12 +241,12 @@ func TestValidateFormType(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { t.Parallel() - if _, ok := formTypesChecked[c.config.String()]; ok { + if _, ok := formTypesChecked.Load(c.config.String()); ok { t.Log("Duplicated form type check, delete this extra test case") t.Fatalf("form type %q already checked", c.config.String()) } - formTypesChecked[c.config.String()] = struct{}{} + formTypesChecked.Store(c.config.String(), struct{}{}) formTypeTest(t, c) }) } @@ -282,7 +283,7 @@ func TestValidateFormType(t *testing.T) { } for _, check := range requiredChecks { - if _, alreadyChecked := formTypesChecked[check.String()]; alreadyChecked { + if _, alreadyChecked := formTypesChecked.Load(check.String()); alreadyChecked { continue } From 3c748041033c3f80effb41fc7c9120f01003d5bd Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 7 May 2025 08:01:02 -0500 Subject: [PATCH 166/173] feat: parameter validation refactored to single function (#381) Validation bugs resolved: - Number parameters require valid number strings - Input values must be in the option set --- provider/parameter.go | 298 +++++++++++++++++---------- provider/parameter_test.go | 187 +++++++++++++++-- provider/testdata/parameter_table.md | 159 +++++++------- 3 files changed, 440 insertions(+), 204 deletions(-) diff --git a/provider/parameter.go b/provider/parameter.go index 2f7dc662..fd484578 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -21,6 +21,10 @@ import ( "golang.org/x/xerrors" ) +var ( + defaultValuePath = cty.Path{cty.GetAttrStep{Name: "default"}} +) + type Option struct { Name string Description string @@ -46,14 +50,13 @@ const ( ) type Parameter struct { - Value string Name string DisplayName string `mapstructure:"display_name"` Description string Type OptionType FormType ParameterFormType Mutable bool - Default string + Default *string Icon string Option []Option Validation []Validation @@ -82,7 +85,6 @@ func parameterDataSource() *schema.Resource { var parameter Parameter err = mapstructure.Decode(struct { - Value interface{} Name interface{} DisplayName interface{} Description interface{} @@ -97,17 +99,22 @@ func parameterDataSource() *schema.Resource { Order interface{} Ephemeral interface{} }{ - Value: rd.Get("value"), Name: rd.Get("name"), DisplayName: rd.Get("display_name"), Description: rd.Get("description"), Type: rd.Get("type"), FormType: rd.Get("form_type"), Mutable: rd.Get("mutable"), - Default: rd.Get("default"), - Icon: rd.Get("icon"), - Option: rd.Get("option"), - Validation: fixedValidation, + Default: func() *string { + if rd.GetRawConfig().AsValueMap()["default"].IsNull() { + return nil + } + val, _ := rd.Get("default").(string) + return &val + }(), + Icon: rd.Get("icon"), + Option: rd.Get("option"), + Validation: fixedValidation, Optional: func() bool { // This hack allows for checking if the "default" field is present in the .tf file. // If "default" is missing or is "null", then it means that this field is required, @@ -122,19 +129,6 @@ func parameterDataSource() *schema.Resource { if err != nil { return diag.Errorf("decode parameter: %s", err) } - var value string - if parameter.Default != "" { - err := valueIsType(parameter.Type, parameter.Default, cty.Path{cty.GetAttrStep{Name: "default"}}) - if err != nil { - return err - } - value = parameter.Default - } - envValue, ok := os.LookupEnv(ParameterEnvironmentVariable(parameter.Name)) - if ok { - value = envValue - } - rd.Set("value", value) if !parameter.Mutable && parameter.Ephemeral { return diag.Errorf("parameter can't be immutable and ephemeral") @@ -144,38 +138,25 @@ func parameterDataSource() *schema.Resource { return diag.Errorf("ephemeral parameter requires the default property") } - // TODO: Should we move this into the Valid() function on - // Parameter? - if len(parameter.Validation) == 1 { - validation := ¶meter.Validation[0] - err = validation.Valid(parameter.Type, value) - if err != nil { - return diag.FromErr(err) - } - } - - // Validate options - _, parameter.FormType, err = ValidateFormType(parameter.Type, len(parameter.Option), parameter.FormType) - if err != nil { - return diag.Diagnostics{ - { - Severity: diag.Error, - Summary: "Invalid form_type for parameter", - Detail: err.Error(), - AttributePath: cty.Path{cty.GetAttrStep{Name: "form_type"}}, - }, - } + var input *string + envValue, ok := os.LookupEnv(ParameterEnvironmentVariable(parameter.Name)) + if ok { + input = &envValue } - // Set the form_type back in case the value was changed. - // Eg via a default. If a user does not specify, a default value - // is used and saved. - rd.Set("form_type", parameter.FormType) - diags := parameter.Valid() + value, diags := parameter.ValidateInput(input) if diags.HasError() { return diags } + // Always set back the value, as it can be sourced from the default + rd.Set("value", value) + + // Set the form_type, as if it was unset, a default form_type will be updated on + // the parameter struct. Always set back the updated form_type to be more + // specific than the default empty string. + rd.Set("form_type", parameter.FormType) + return nil }, Schema: map[string]*schema.Schema{ @@ -389,37 +370,49 @@ func fixValidationResourceData(rawConfig cty.Value, validation interface{}) (int return vArr, nil } -func valueIsType(typ OptionType, value string, attrPath cty.Path) diag.Diagnostics { +func valueIsType(typ OptionType, value string) error { switch typ { case OptionTypeNumber: _, err := strconv.ParseFloat(value, 64) if err != nil { - return diag.Errorf("%q is not a number", value) + return fmt.Errorf("%q is not a number", value) } case OptionTypeBoolean: _, err := strconv.ParseBool(value) if err != nil { - return diag.Errorf("%q is not a bool", value) + return fmt.Errorf("%q is not a bool", value) } case OptionTypeListString: - _, diags := valueIsListString(value, attrPath) - if diags.HasError() { - return diags + _, err := valueIsListString(value) + if err != nil { + return err } case OptionTypeString: // Anything is a string! default: - return diag.Errorf("invalid type %q", typ) + return fmt.Errorf("invalid type %q", typ) } return nil } -func (v *Parameter) Valid() diag.Diagnostics { +func (v *Parameter) ValidateInput(input *string) (string, diag.Diagnostics) { + var err error + var optionType OptionType + + valuePath := cty.Path{} + value := input + if input == nil { + value = v.Default + if v.Default != nil { + valuePath = defaultValuePath + } + } + // optionType might differ from parameter.Type. This is ok, and parameter.Type // should be used for the value type, and optionType for options. - optionType, _, err := ValidateFormType(v.Type, len(v.Option), v.FormType) + optionType, v.FormType, err = ValidateFormType(v.Type, len(v.Option), v.FormType) if err != nil { - return diag.Diagnostics{ + return "", diag.Diagnostics{ { Severity: diag.Error, Summary: "Invalid form_type for parameter", @@ -429,53 +422,120 @@ func (v *Parameter) Valid() diag.Diagnostics { } } - optionNames := map[string]any{} - optionValues := map[string]any{} - if len(v.Option) > 0 { - for _, option := range v.Option { - _, exists := optionNames[option.Name] - if exists { - return diag.Diagnostics{{ - Severity: diag.Error, - Summary: "Option names must be unique.", - Detail: fmt.Sprintf("multiple options found with the same name %q", option.Name), - }, - } - } - _, exists = optionValues[option.Value] - if exists { - return diag.Diagnostics{ - { - Severity: diag.Error, - Summary: "Option values must be unique.", - Detail: fmt.Sprintf("multiple options found with the same value %q", option.Value), - }, - } - } - diags := valueIsType(optionType, option.Value, cty.Path{}) - if diags.HasError() { - return diags - } - optionValues[option.Value] = nil - optionNames[option.Name] = nil + optionValues, diags := v.ValidOptions(optionType) + if diags.HasError() { + return "", diags + } + + // TODO: This is a bit of a hack. The current behavior states if validation + // is given, then apply validation to unset values. + // value == nil should not be accepted in the first place. + // To fix this, value should be coerced to an empty string + // if it is nil. Then let the validation logic always apply. + if len(v.Validation) == 0 && value == nil { + return "", nil + } + + // forcedValue ensures the value is not-nil. + var forcedValue string + if value != nil { + forcedValue = *value + } + + d := v.validValue(forcedValue, optionType, optionValues, valuePath) + if d.HasError() { + return "", d + } + + err = valueIsType(v.Type, forcedValue) + if err != nil { + return "", diag.Diagnostics{ + { + Severity: diag.Error, + Summary: fmt.Sprintf("Parameter value is not of type %q", v.Type), + Detail: err.Error(), + }, } } - if v.Default != "" && len(v.Option) > 0 { + return forcedValue, nil +} + +func (v *Parameter) ValidOptions(optionType OptionType) (map[string]struct{}, diag.Diagnostics) { + optionNames := map[string]struct{}{} + optionValues := map[string]struct{}{} + + var diags diag.Diagnostics + for _, option := range v.Option { + _, exists := optionNames[option.Name] + if exists { + return nil, diag.Diagnostics{{ + Severity: diag.Error, + Summary: "Option names must be unique.", + Detail: fmt.Sprintf("multiple options found with the same name %q", option.Name), + }} + } + + _, exists = optionValues[option.Value] + if exists { + return nil, diag.Diagnostics{{ + Severity: diag.Error, + Summary: "Option values must be unique.", + Detail: fmt.Sprintf("multiple options found with the same value %q", option.Value), + }} + } + + err := valueIsType(optionType, option.Value) + if err != nil { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: fmt.Sprintf("Option %q with value=%q is not of type %q", option.Name, option.Value, optionType), + Detail: err.Error(), + }) + continue + } + optionValues[option.Value] = struct{}{} + optionNames[option.Name] = struct{}{} + + // Option values are assumed to be valid. Do not call validValue on them. + } + + if diags != nil && diags.HasError() { + return nil, diags + } + return optionValues, nil +} + +func (v *Parameter) validValue(value string, optionType OptionType, optionValues map[string]struct{}, path cty.Path) diag.Diagnostics { + // name is used for constructing more precise error messages. + name := "Value" + if path.Equals(defaultValuePath) { + name = "Default value" + } + + // First validate if the value is a valid option + if len(optionValues) > 0 { if v.Type == OptionTypeListString && optionType == OptionTypeString { // If the type is list(string) and optionType is string, we have - // to ensure all elements of the default exist as options. - defaultValues, diags := valueIsListString(v.Default, cty.Path{cty.GetAttrStep{Name: "default"}}) - if diags.HasError() { - return diags + // to ensure all elements of the value exist as options. + listValues, err := valueIsListString(value) + if err != nil { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "When using list(string) type, value must be a json encoded list of strings", + Detail: err.Error(), + AttributePath: path, + }, + } } // missing is used to construct a more helpful error message var missing []string - for _, defaultValue := range defaultValues { - _, defaultIsValid := optionValues[defaultValue] - if !defaultIsValid { - missing = append(missing, defaultValue) + for _, listValue := range listValues { + _, isValid := optionValues[listValue] + if !isValid { + missing = append(missing, listValue) } } @@ -483,30 +543,49 @@ func (v *Parameter) Valid() diag.Diagnostics { return diag.Diagnostics{ { Severity: diag.Error, - Summary: "Default values must be a valid option", + Summary: fmt.Sprintf("%ss must be a valid option", name), Detail: fmt.Sprintf( - "default value %q is not a valid option, values %q are missing from the options", - v.Default, strings.Join(missing, ", "), + "%s %q is not a valid option, values %q are missing from the options", + name, value, strings.Join(missing, ", "), ), - AttributePath: cty.Path{cty.GetAttrStep{Name: "default"}}, + AttributePath: path, }, } } } else { - _, defaultIsValid := optionValues[v.Default] - if !defaultIsValid { + _, isValid := optionValues[value] + if !isValid { + extra := "" + if value == "" { + extra = ". The value is empty, did you forget to set it with a default or from user input?" + } return diag.Diagnostics{ { Severity: diag.Error, - Summary: "Default value must be a valid option", - Detail: fmt.Sprintf("the value %q must be defined as one of options", v.Default), - AttributePath: cty.Path{cty.GetAttrStep{Name: "default"}}, + Summary: fmt.Sprintf("%s must be a valid option%s", name, extra), + Detail: fmt.Sprintf("the value %q must be defined as one of options", value), + AttributePath: path, }, } } } } + if len(v.Validation) == 1 { + validCheck := &v.Validation[0] + err := validCheck.Valid(v.Type, value) + if err != nil { + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: fmt.Sprintf("Invalid parameter %s according to 'validation' block", strings.ToLower(name)), + Detail: err.Error(), + AttributePath: path, + }, + } + } + } + return nil } @@ -570,18 +649,11 @@ func (v *Validation) Valid(typ OptionType, value string) error { return nil } -func valueIsListString(value string, path cty.Path) ([]string, diag.Diagnostics) { +func valueIsListString(value string) ([]string, error) { var items []string err := json.Unmarshal([]byte(value), &items) if err != nil { - return nil, diag.Diagnostics{ - { - Severity: diag.Error, - Summary: "When using list(string) type, value must be a json encoded list of strings", - Detail: fmt.Sprintf("value %q is not a valid list of strings", value), - AttributePath: path, - }, - } + return nil, fmt.Errorf("value %q is not a valid list of strings", value) } return items, nil } diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 32877c2b..21842b6a 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/coder/terraform-provider-coder/v2/provider" @@ -84,6 +85,7 @@ func TestParameter(t *testing.T) { data "coder_parameter" "region" { name = "Region" type = "number" + default = 1 option { name = "1" value = "1" @@ -101,6 +103,7 @@ func TestParameter(t *testing.T) { data "coder_parameter" "region" { name = "Region" type = "string" + default = "1" option { name = "1" value = "1" @@ -688,6 +691,168 @@ data "coder_parameter" "region" { } } +func TestParameterValidation(t *testing.T) { + t.Parallel() + opts := func(vals ...string) []provider.Option { + options := make([]provider.Option, 0, len(vals)) + for _, val := range vals { + options = append(options, provider.Option{ + Name: val, + Value: val, + }) + } + return options + } + + for _, tc := range []struct { + Name string + Parameter provider.Parameter + Value string + ExpectError *regexp.Regexp + }{ + { + Name: "ValidStringParameter", + Parameter: provider.Parameter{ + Type: "string", + }, + Value: "alpha", + }, + // Test invalid states + { + Name: "InvalidFormType", + Parameter: provider.Parameter{ + Type: "string", + Option: opts("alpha", "bravo", "charlie"), + FormType: provider.ParameterFormTypeSlider, + }, + Value: "alpha", + ExpectError: regexp.MustCompile("Invalid form_type for parameter"), + }, + { + Name: "NotInOptions", + Parameter: provider.Parameter{ + Type: "string", + Option: opts("alpha", "bravo", "charlie"), + }, + Value: "delta", // not in option set + ExpectError: regexp.MustCompile("Value must be a valid option"), + }, + { + Name: "NumberNotInOptions", + Parameter: provider.Parameter{ + Type: "number", + Option: opts("1", "2", "3"), + }, + Value: "0", // not in option set + ExpectError: regexp.MustCompile("Value must be a valid option"), + }, + { + Name: "NonUniqueOptionNames", + Parameter: provider.Parameter{ + Type: "string", + Option: opts("alpha", "alpha"), + }, + Value: "alpha", + ExpectError: regexp.MustCompile("Option names must be unique"), + }, + { + Name: "NonUniqueOptionValues", + Parameter: provider.Parameter{ + Type: "string", + Option: []provider.Option{ + {Name: "Alpha", Value: "alpha"}, + {Name: "AlphaAgain", Value: "alpha"}, + }, + }, + Value: "alpha", + ExpectError: regexp.MustCompile("Option values must be unique"), + }, + { + Name: "IncorrectValueTypeOption", + Parameter: provider.Parameter{ + Type: "number", + Option: opts("not-a-number"), + }, + Value: "5", + ExpectError: regexp.MustCompile("is not a number"), + }, + { + Name: "IncorrectValueType", + Parameter: provider.Parameter{ + Type: "number", + }, + Value: "not-a-number", + ExpectError: regexp.MustCompile("Parameter value is not of type \"number\""), + }, + { + Name: "NotListStringDefault", + Parameter: provider.Parameter{ + Type: "list(string)", + Default: ptr("not-a-list"), + }, + ExpectError: regexp.MustCompile("not a valid list of strings"), + }, + { + Name: "NotListStringDefault", + Parameter: provider.Parameter{ + Type: "list(string)", + }, + Value: "not-a-list", + ExpectError: regexp.MustCompile("not a valid list of strings"), + }, + { + Name: "DefaultListStringNotInOptions", + Parameter: provider.Parameter{ + Type: "list(string)", + Default: ptr(`["red", "yellow", "black"]`), + Option: opts("red", "blue", "green"), + FormType: provider.ParameterFormTypeMultiSelect, + }, + Value: `["red", "yellow", "black"]`, + ExpectError: regexp.MustCompile("is not a valid option, values \"yellow, black\" are missing from the options"), + }, + { + Name: "ListStringNotInOptions", + Parameter: provider.Parameter{ + Type: "list(string)", + Default: ptr(`["red"]`), + Option: opts("red", "blue", "green"), + FormType: provider.ParameterFormTypeMultiSelect, + }, + Value: `["red", "yellow", "black"]`, + ExpectError: regexp.MustCompile("is not a valid option, values \"yellow, black\" are missing from the options"), + }, + { + Name: "InvalidMiniumum", + Parameter: provider.Parameter{ + Type: "number", + Default: ptr("5"), + Validation: []provider.Validation{{ + Min: 10, + Error: "must be greater than 10", + }}, + }, + ExpectError: regexp.MustCompile("must be greater than 10"), + }, + } { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + t.Parallel() + value := &tc.Value + _, diags := tc.Parameter.ValidateInput(value) + if tc.ExpectError != nil { + require.True(t, diags.HasError()) + errMsg := fmt.Sprintf("%+v", diags[0]) // close enough + require.Truef(t, tc.ExpectError.MatchString(errMsg), "got: %s", errMsg) + } else { + if !assert.False(t, diags.HasError()) { + t.Logf("got: %+v", diags[0]) + } + } + }) + } +} + // TestParameterValidationEnforcement tests various parameter states and the // validation enforcement that should be applied to them. The table is described // by a markdown table. This is done so that the test cases can be more easily @@ -703,10 +868,6 @@ func TestParameterValidationEnforcement(t *testing.T) { // - Validation logic does not apply to the default if a value is given // - [NumIns/DefInv] So the default can be invalid if an input value is valid. // The value is therefore not really optional, but it is marked as such. - // - [NumInsNotOptsVal | NumsInsNotOpts] values do not need to be in the option set? - // - [NumInsNotNum] number params do not require the value to be a number - // - [LStrInsNotList] list(string) do not require the value to be a list(string) - // - Same with [MulInsNotListOpts] table, err := os.ReadFile("testdata/parameter_table.md") require.NoError(t, err) @@ -719,7 +880,7 @@ func TestParameterValidationEnforcement(t *testing.T) { Validation *provider.Validation OutputValue string Optional bool - Error *regexp.Regexp + CreateError *regexp.Regexp } rows := make([]row, 0) @@ -750,6 +911,7 @@ func TestParameterValidationEnforcement(t *testing.T) { t.Fatalf("failed to parse error column %q: %v", columns[9], err) } } + var options []string if columns[4] != "" { options = strings.Split(columns[4], ",") @@ -796,7 +958,7 @@ func TestParameterValidationEnforcement(t *testing.T) { Validation: validation, OutputValue: columns[7], Optional: optional, - Error: rerr, + CreateError: rerr, }) } @@ -815,10 +977,8 @@ func TestParameterValidationEnforcement(t *testing.T) { t.Setenv(provider.ParameterEnvironmentVariable("parameter"), row.InputValue) } - if row.Error != nil { - if row.OutputValue != "" { - t.Errorf("output value %q should not be set if error is set", row.OutputValue) - } + if row.CreateError != nil && row.OutputValue != "" { + t.Errorf("output value %q should not be set if both errors are set", row.OutputValue) } var cfg strings.Builder @@ -860,13 +1020,12 @@ func TestParameterValidationEnforcement(t *testing.T) { } cfg.WriteString("}\n") - resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(), IsUnitTest: true, Steps: []resource.TestStep{{ Config: cfg.String(), - ExpectError: row.Error, + ExpectError: row.CreateError, Check: func(state *terraform.State) error { require.Len(t, state.Modules, 1) require.Len(t, state.Modules[0].Resources, 1) @@ -1096,3 +1255,7 @@ func TestParameterWithManyOptions(t *testing.T) { }}, }) } + +func ptr[T any](v T) *T { + return &v +} diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md index f7645efa..3df16f06 100644 --- a/provider/testdata/parameter_table.md +++ b/provider/testdata/parameter_table.md @@ -1,79 +1,80 @@ -| Name | Type | Input | Default | Options | Validation | -> | Output | Optional | Error | -|----------------------|---------------|-----------|---------|-------------------|------------|----|--------|----------|--------------| -| | Empty Vals | | | | | | | | | -| Empty | string,number | | | | | | "" | false | | -| EmptyDupeOps | string,number | | | 1,1,1 | | | | | unique | -| EmptyList | list(string) | | | | | | "" | false | | -| EmptyListDupeOpts | list(string) | | | ["a"],["a"] | | | | | unique | -| EmptyMulti | tag-select | | | | | | "" | false | | -| EmptyOpts | string,number | | | 1,2,3 | | | "" | false | | -| EmptyRegex | string | | | | world | | | | regex error | -| EmptyMin | number | | | | 1-10 | | | | 1 < < 10 | -| EmptyMinOpt | number | | | 1,2,3 | 2-5 | | | | 2 < < 5 | -| EmptyRegexOpt | string | | | "hello","goodbye" | goodbye | | | | regex error | -| EmptyRegexOk | string | | | | .* | | "" | false | | -| | | | | | | | | | | -| | Default Set | No inputs | | | | | | | | -| NumDef | number | | 5 | | | | 5 | true | | -| NumDefVal | number | | 5 | | 3-7 | | 5 | true | | -| NumDefInv | number | | 5 | | 10- | | | | 10 < 5 < 0 | -| NumDefOpts | number | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | -| NumDefNotOpts | number | | 5 | 1,3,7,9 | 2-6 | | | | valid option | -| NumDefInvOpt | number | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | -| NumDefNotNum | number | | a | | | | | | a number | -| NumDefOptsNotNum | number | | 1 | 1,a,2 | | | | | a number | -| | | | | | | | | | | -| StrDef | string | | hello | | | | hello | true | | -| StrDefInv | string | | hello | | world | | | | regex error | -| StrDefOpts | string | | a | a,b,c | | | a | true | | -| StrDefNotOpts | string | | a | b,c,d | | | | | valid option | -| StrDefValOpts | string | | a | a,b,c,d,e,f | [a-c] | | a | true | | -| StrDefInvOpt | string | | d | a,b,c,d,e,f | [a-c] | | | | regex error | -| | | | | | | | | | | -| LStrDef | list(string) | | ["a"] | | | | ["a"] | true | | -| LStrDefOpts | list(string) | | ["a"] | ["a"], ["b"] | | | ["a"] | true | | -| LStrDefNotOpts | list(string) | | ["a"] | ["b"], ["c"] | | | | | valid option | -| | | | | | | | | | | -| MulDef | tag-select | | ["a"] | | | | ["a"] | true | | -| MulDefOpts | multi-select | | ["a"] | a,b | | | ["a"] | true | | -| MulDefNotOpts | multi-select | | ["a"] | b,c | | | | | valid option | -| | | | | | | | | | | -| | Input Vals | | | | | | | | | -| NumIns | number | 3 | | | | | 3 | false | | -| NumInsNotNum | number | a | | | | | a | false | | -| NumInsNotNumInv | number | a | | | 1-3 | | | | 1 < a < 3 | -| NumInsDef | number | 3 | 5 | | | | 3 | true | | -| NumIns/DefInv | number | 3 | 5 | | 1-3 | | 3 | true | | -| NumIns=DefInv | number | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | -| NumInsOpts | number | 3 | 5 | 1,2,3,4,5 | 1-3 | | 3 | true | | -| NumInsNotOptsVal | number | 3 | 5 | 1,2,4,5 | 1-3 | | 3 | true | | -| NumInsNotOptsInv | number | 3 | 5 | 1,2,4,5 | 1-2 | | | true | 1 < 3 < 2 | -| NumInsNotOpts | number | 3 | 5 | 1,2,4,5 | | | 3 | true | | -| NumInsNotOpts/NoDef | number | 3 | | 1,2,4,5 | | | 3 | false | | -| | | | | | | | | | | -| StrIns | string | c | | | | | c | false | | -| StrInsDupeOpts | string | c | | a,b,c,c | | | | | unique | -| StrInsDef | string | c | e | | | | c | true | | -| StrIns/DefInv | string | c | e | | [a-c] | | c | true | | -| StrIns=DefInv | string | e | e | | [a-c] | | | | regex error | -| StrInsOpts | string | c | e | a,b,c,d,e | [a-c] | | c | true | | -| StrInsNotOptsVal | string | c | e | a,b,d,e | [a-c] | | c | true | | -| StrInsNotOptsInv | string | c | e | a,b,d,e | [a-b] | | | | regex error | -| StrInsNotOpts | string | c | e | a,b,d,e | | | c | true | | -| StrInsNotOpts/NoDef | string | c | | a,b,d,e | | | c | false | | -| StrInsBadVal | string | c | | a,b,c,d,e | 1-10 | | | | min cannot | -| | | | | | | | | | | -| | list(string) | | | | | | | | | -| LStrIns | list(string) | ["c"] | | | | | ["c"] | false | | -| LStrInsNotList | list(string) | c | | | | | c | false | | -| LStrInsDef | list(string) | ["c"] | ["e"] | | | | ["c"] | true | | -| LStrIns/DefInv | list(string) | ["c"] | ["e"] | | [a-c] | | | | regex cannot | -| LStrInsOpts | list(string) | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | -| LStrInsNotOpts | list(string) | ["c"] | ["e"] | ["d"],["e"] | | | ["c"] | true | | -| LStrInsNotOpts/NoDef | list(string) | ["c"] | | ["d"],["e"] | | | ["c"] | false | | -| | | | | | | | | | | -| MulInsOpts | multi-select | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | -| MulInsNotListOpts | multi-select | c | ["e"] | c,d,e | | | c | true | | -| MulInsNotOpts | multi-select | ["c"] | ["e"] | d,e | | | ["c"] | true | | -| MulInsNotOpts/NoDef | multi-select | ["c"] | | d,e | | | ["c"] | false | | -| MulInsInvOpts | multi-select | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file +| Name | Type | Input | Default | Options | Validation | -> | Output | Optional | ErrorCreate | +|----------------------|---------------|-----------|---------|-------------------|------------|----|--------|----------|-----------------| +| | Empty Vals | | | | | | | | | +| Empty | string,number | | | | | | "" | false | | +| EmptyDupeOps | string,number | | | 1,1,1 | | | | | unique | +| EmptyList | list(string) | | | | | | "" | false | | +| EmptyListDupeOpts | list(string) | | | ["a"],["a"] | | | | | unique | +| EmptyMulti | tag-select | | | | | | "" | false | | +| EmptyOpts | string,number | | | 1,2,3 | | | "" | false | | +| EmptyRegex | string | | | | world | | | | regex error | +| EmptyMin | number | | | | 1-10 | | | | 1 < < 10 | +| EmptyMinOpt | number | | | 1,2,3 | 2-5 | | | | valid option | +| EmptyRegexOpt | string | | | "hello","goodbye" | goodbye | | | | valid option | +| EmptyRegexOk | string | | | | .* | | "" | false | | +| | | | | | | | | | | +| | Default Set | No inputs | | | | | | | | +| NumDef | number | | 5 | | | | 5 | true | | +| NumDefVal | number | | 5 | | 3-7 | | 5 | true | | +| NumDefInv | number | | 5 | | 10- | | | | 10 < 5 < 0 | +| NumDefOpts | number | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | +| NumDefNotOpts | number | | 5 | 1,3,7,9 | 2-6 | | | | valid option | +| NumDefInvOpt | number | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | +| NumDefNotNum | number | | a | | | | | | type "number" | +| NumDefOptsNotNum | number | | 1 | 1,a,2 | | | | | type "number" | +| | | | | | | | | | | +| StrDef | string | | hello | | | | hello | true | | +| StrDefInv | string | | hello | | world | | | | regex error | +| StrDefOpts | string | | a | a,b,c | | | a | true | | +| StrDefNotOpts | string | | a | b,c,d | | | | | valid option | +| StrDefValOpts | string | | a | a,b,c,d,e,f | [a-c] | | a | true | | +| StrDefInvOpt | string | | d | a,b,c,d,e,f | [a-c] | | | | regex error | +| | | | | | | | | | | +| LStrDef | list(string) | | ["a"] | | | | ["a"] | true | | +| LStrDefOpts | list(string) | | ["a"] | ["a"], ["b"] | | | ["a"] | true | | +| LStrDefNotOpts | list(string) | | ["a"] | ["b"], ["c"] | | | | | valid option | +| | | | | | | | | | | +| MulDef | tag-select | | ["a"] | | | | ["a"] | true | | +| MulDefOpts | multi-select | | ["a"] | a,b | | | ["a"] | true | | +| MulDefNotOpts | multi-select | | ["a"] | b,c | | | | | valid option | +| | | | | | | | | | | +| | Input Vals | | | | | | | | | +| NumIns | number | 3 | | | | | 3 | false | | +| NumInsOptsNaN | number | 3 | 5 | a,1,2,3,4,5 | 1-3 | | | | type "number" | +| NumInsNotNum | number | a | | | | | | | type "number" | +| NumInsNotNumInv | number | a | | | 1-3 | | | | 1 < a < 3 | +| NumInsDef | number | 3 | 5 | | | | 3 | true | | +| NumIns/DefInv | number | 3 | 5 | | 1-3 | | 3 | true | | +| NumIns=DefInv | number | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | +| NumInsOpts | number | 3 | 5 | 1,2,3,4,5 | 1-3 | | 3 | true | | +| NumInsNotOptsVal | number | 3 | 5 | 1,2,4,5 | 1-3 | | | | valid option | +| NumInsNotOptsInv | number | 3 | 5 | 1,2,4,5 | 1-2 | | | true | valid option | +| NumInsNotOpts | number | 3 | 5 | 1,2,4,5 | | | | | valid option | +| NumInsNotOpts/NoDef | number | 3 | | 1,2,4,5 | | | | | valid option | +| | | | | | | | | | | +| StrIns | string | c | | | | | c | false | | +| StrInsDupeOpts | string | c | | a,b,c,c | | | | | unique | +| StrInsDef | string | c | e | | | | c | true | | +| StrIns/DefInv | string | c | e | | [a-c] | | c | true | | +| StrIns=DefInv | string | e | e | | [a-c] | | | | regex error | +| StrInsOpts | string | c | e | a,b,c,d,e | [a-c] | | c | true | | +| StrInsNotOptsVal | string | c | e | a,b,d,e | [a-c] | | | | valid option | +| StrInsNotOptsInv | string | c | e | a,b,d,e | [a-b] | | | | valid option | +| StrInsNotOpts | string | c | e | a,b,d,e | | | | | valid option | +| StrInsNotOpts/NoDef | string | c | | a,b,d,e | | | | | valid option | +| StrInsBadVal | string | c | | a,b,c,d,e | 1-10 | | | | min cannot | +| | | | | | | | | | | +| | list(string) | | | | | | | | | +| LStrIns | list(string) | ["c"] | | | | | ["c"] | false | | +| LStrInsNotList | list(string) | c | | | | | | | list of strings | +| LStrInsDef | list(string) | ["c"] | ["e"] | | | | ["c"] | true | | +| LStrIns/DefInv | list(string) | ["c"] | ["e"] | | [a-c] | | | | regex cannot | +| LStrInsOpts | list(string) | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | +| LStrInsNotOpts | list(string) | ["c"] | ["e"] | ["d"],["e"] | | | | | valid option | +| LStrInsNotOpts/NoDef | list(string) | ["c"] | | ["d"],["e"] | | | | | valid option | +| | | | | | | | | | | +| MulInsOpts | multi-select | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | +| MulInsNotListOpts | multi-select | c | ["e"] | c,d,e | | | | | json encoded | +| MulInsNotOpts | multi-select | ["c"] | ["e"] | d,e | | | | | valid option | +| MulInsNotOpts/NoDef | multi-select | ["c"] | | d,e | | | | | valid option | +| MulInsInvOpts | multi-select | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file From 8692a56f55acb7a10f74c16f7f00b896c33ce02b Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 8 May 2025 09:36:57 -0500 Subject: [PATCH 167/173] feat: enforce monotonicity in terraform provider (#392) Previous value must come from env var. --- provider/parameter.go | 55 ++++++++- provider/parameter_test.go | 120 ++++++++++++++---- provider/testdata/parameter_table.md | 175 +++++++++++++++------------ 3 files changed, 241 insertions(+), 109 deletions(-) diff --git a/provider/parameter.go b/provider/parameter.go index fd484578..f0a26c99 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -144,7 +144,13 @@ func parameterDataSource() *schema.Resource { input = &envValue } - value, diags := parameter.ValidateInput(input) + var previous *string + envPreviousValue, ok := os.LookupEnv(ParameterEnvironmentVariablePrevious(parameter.Name)) + if ok { + previous = &envPreviousValue + } + + value, diags := parameter.ValidateInput(input, previous) if diags.HasError() { return diags } @@ -395,7 +401,7 @@ func valueIsType(typ OptionType, value string) error { return nil } -func (v *Parameter) ValidateInput(input *string) (string, diag.Diagnostics) { +func (v *Parameter) ValidateInput(input *string, previous *string) (string, diag.Diagnostics) { var err error var optionType OptionType @@ -442,7 +448,7 @@ func (v *Parameter) ValidateInput(input *string) (string, diag.Diagnostics) { forcedValue = *value } - d := v.validValue(forcedValue, optionType, optionValues, valuePath) + d := v.validValue(forcedValue, previous, optionType, optionValues, valuePath) if d.HasError() { return "", d } @@ -506,7 +512,7 @@ func (v *Parameter) ValidOptions(optionType OptionType) (map[string]struct{}, di return optionValues, nil } -func (v *Parameter) validValue(value string, optionType OptionType, optionValues map[string]struct{}, path cty.Path) diag.Diagnostics { +func (v *Parameter) validValue(value string, previous *string, optionType OptionType, optionValues map[string]struct{}, path cty.Path) diag.Diagnostics { // name is used for constructing more precise error messages. name := "Value" if path.Equals(defaultValuePath) { @@ -573,7 +579,7 @@ func (v *Parameter) validValue(value string, optionType OptionType, optionValues if len(v.Validation) == 1 { validCheck := &v.Validation[0] - err := validCheck.Valid(v.Type, value) + err := validCheck.Valid(v.Type, value, previous) if err != nil { return diag.Diagnostics{ { @@ -589,7 +595,7 @@ func (v *Parameter) validValue(value string, optionType OptionType, optionValues return nil } -func (v *Validation) Valid(typ OptionType, value string) error { +func (v *Validation) Valid(typ OptionType, value string, previous *string) error { if typ != OptionTypeNumber { if !v.MinDisabled { return fmt.Errorf("a min cannot be specified for a %s type", typ) @@ -639,6 +645,34 @@ func (v *Validation) Valid(typ OptionType, value string) error { if v.Monotonic != "" && v.Monotonic != ValidationMonotonicIncreasing && v.Monotonic != ValidationMonotonicDecreasing { return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing) } + + switch v.Monotonic { + case "": + // No monotonicity check + case ValidationMonotonicIncreasing, ValidationMonotonicDecreasing: + if previous != nil { // Only check if previous value exists + previousNum, err := strconv.Atoi(*previous) + if err != nil { + // Do not throw an error for the previous value not being a number. Throwing an + // error here would cause an unrepairable state for the user. This is + // unfortunate, but there is not much we can do at this point. + // TODO: Maybe we should enforce this, and have the calling coderd + // do something to resolve it. Such as doing this check before calling + // terraform apply. + break + } + + if v.Monotonic == ValidationMonotonicIncreasing && !(num >= previousNum) { + return fmt.Errorf("parameter value '%d' must be equal or greater than previous value: %d", num, previousNum) + } + + if v.Monotonic == ValidationMonotonicDecreasing && !(num <= previousNum) { + return fmt.Errorf("parameter value '%d' must be equal or lower than previous value: %d", num, previousNum) + } + } + default: + return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing) + } case OptionTypeListString: var listOfStrings []string err := json.Unmarshal([]byte(value), &listOfStrings) @@ -666,6 +700,15 @@ func ParameterEnvironmentVariable(name string) string { return "CODER_PARAMETER_" + hex.EncodeToString(sum[:]) } +// ParameterEnvironmentVariablePrevious returns the environment variable to +// specify for a parameter's previous value. This is used for workspace +// subsequent builds after the first. Primarily to validate monotonicity in the +// `validation` block. +func ParameterEnvironmentVariablePrevious(name string) string { + sum := sha256.Sum256([]byte(name)) + return "CODER_PARAMETER_PREVIOUS_" + hex.EncodeToString(sum[:]) +} + func takeFirstError(errs ...error) error { for _, err := range errs { if err != nil { diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 21842b6a..9b5e76f1 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -839,7 +839,7 @@ func TestParameterValidation(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { t.Parallel() value := &tc.Value - _, diags := tc.Parameter.ValidateInput(value) + _, diags := tc.Parameter.ValidateInput(value, nil) if tc.ExpectError != nil { require.True(t, diags.HasError()) errMsg := fmt.Sprintf("%+v", diags[0]) // close enough @@ -881,6 +881,7 @@ func TestParameterValidationEnforcement(t *testing.T) { OutputValue string Optional bool CreateError *regexp.Regexp + Previous *string } rows := make([]row, 0) @@ -898,33 +899,44 @@ func TestParameterValidationEnforcement(t *testing.T) { continue // Skip rows with empty names } - optional, err := strconv.ParseBool(columns[8]) - if columns[8] != "" { + cname, ctype, cprev, cinput, cdefault, coptions, cvalidation, _, coutput, coptional, cerr := + columns[0], columns[1], columns[2], columns[3], columns[4], columns[5], columns[6], columns[7], columns[8], columns[9], columns[10] + + optional, err := strconv.ParseBool(coptional) + if coptional != "" { // Value does not matter if not specified require.NoError(t, err) } var rerr *regexp.Regexp - if columns[9] != "" { - rerr, err = regexp.Compile(columns[9]) + if cerr != "" { + rerr, err = regexp.Compile(cerr) if err != nil { - t.Fatalf("failed to parse error column %q: %v", columns[9], err) + t.Fatalf("failed to parse error column %q: %v", cerr, err) } } var options []string - if columns[4] != "" { - options = strings.Split(columns[4], ",") + if coptions != "" { + options = strings.Split(coptions, ",") } var validation *provider.Validation - if columns[5] != "" { - // Min-Max validation should look like: - // 1-10 :: min=1, max=10 - // -10 :: max=10 - // 1- :: min=1 - if validMinMax.MatchString(columns[5]) { - parts := strings.Split(columns[5], "-") + if cvalidation != "" { + switch { + case cvalidation == provider.ValidationMonotonicIncreasing || cvalidation == provider.ValidationMonotonicDecreasing: + validation = &provider.Validation{ + MinDisabled: true, + MaxDisabled: true, + Monotonic: cvalidation, + Error: "monotonicity", + } + case validMinMax.MatchString(cvalidation): + // Min-Max validation should look like: + // 1-10 :: min=1, max=10 + // -10 :: max=10 + // 1- :: min=1 + parts := strings.Split(cvalidation, "-") min, _ := strconv.ParseInt(parts[0], 10, 64) max, _ := strconv.ParseInt(parts[1], 10, 64) validation = &provider.Validation{ @@ -936,29 +948,37 @@ func TestParameterValidationEnforcement(t *testing.T) { Regex: "", Error: "{min} < {value} < {max}", } - } else { + default: validation = &provider.Validation{ Min: 0, MinDisabled: true, Max: 0, MaxDisabled: true, Monotonic: "", - Regex: columns[5], + Regex: cvalidation, Error: "regex error", } } } + var prev *string + if cprev != "" { + prev = ptr(cprev) + if cprev == `""` { + prev = ptr("") + } + } rows = append(rows, row{ - Name: columns[0], - Types: strings.Split(columns[1], ","), - InputValue: columns[2], - Default: columns[3], + Name: cname, + Types: strings.Split(ctype, ","), + InputValue: cinput, + Default: cdefault, Options: options, Validation: validation, - OutputValue: columns[7], + OutputValue: coutput, Optional: optional, CreateError: rerr, + Previous: prev, }) } @@ -976,6 +996,9 @@ func TestParameterValidationEnforcement(t *testing.T) { if row.InputValue != "" { t.Setenv(provider.ParameterEnvironmentVariable("parameter"), row.InputValue) } + if row.Previous != nil { + t.Setenv(provider.ParameterEnvironmentVariablePrevious("parameter"), *row.Previous) + } if row.CreateError != nil && row.OutputValue != "" { t.Errorf("output value %q should not be set if both errors are set", row.OutputValue) @@ -1067,6 +1090,7 @@ func TestValueValidatesType(t *testing.T) { Name string Type provider.OptionType Value string + Previous *string Regex string RegexError string Min int @@ -1154,6 +1178,56 @@ func TestValueValidatesType(t *testing.T) { Min: 0, Max: 2, Monotonic: "decreasing", + }, { + Name: "IncreasingMonotonicityEqual", + Type: "number", + Previous: ptr("1"), + Value: "1", + Monotonic: "increasing", + MinDisabled: true, + MaxDisabled: true, + }, { + Name: "DecreasingMonotonicityEqual", + Type: "number", + Value: "1", + Previous: ptr("1"), + Monotonic: "decreasing", + MinDisabled: true, + MaxDisabled: true, + }, { + Name: "IncreasingMonotonicityGreater", + Type: "number", + Previous: ptr("0"), + Value: "1", + Monotonic: "increasing", + MinDisabled: true, + MaxDisabled: true, + }, { + Name: "DecreasingMonotonicityGreater", + Type: "number", + Value: "1", + Previous: ptr("0"), + Monotonic: "decreasing", + MinDisabled: true, + MaxDisabled: true, + Error: regexp.MustCompile("must be equal or"), + }, { + Name: "IncreasingMonotonicityLesser", + Type: "number", + Previous: ptr("2"), + Value: "1", + Monotonic: "increasing", + MinDisabled: true, + MaxDisabled: true, + Error: regexp.MustCompile("must be equal or"), + }, { + Name: "DecreasingMonotonicityLesser", + Type: "number", + Value: "1", + Previous: ptr("2"), + Monotonic: "decreasing", + MinDisabled: true, + MaxDisabled: true, }, { Name: "ValidListOfStrings", Type: "list(string)", @@ -1205,7 +1279,7 @@ func TestValueValidatesType(t *testing.T) { Regex: tc.Regex, Error: tc.RegexError, } - err := v.Valid(tc.Type, tc.Value) + err := v.Valid(tc.Type, tc.Value, tc.Previous) if tc.Error != nil { require.Error(t, err) require.True(t, tc.Error.MatchString(err.Error()), "got: %s", err.Error()) diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md index 3df16f06..6087460f 100644 --- a/provider/testdata/parameter_table.md +++ b/provider/testdata/parameter_table.md @@ -1,80 +1,95 @@ -| Name | Type | Input | Default | Options | Validation | -> | Output | Optional | ErrorCreate | -|----------------------|---------------|-----------|---------|-------------------|------------|----|--------|----------|-----------------| -| | Empty Vals | | | | | | | | | -| Empty | string,number | | | | | | "" | false | | -| EmptyDupeOps | string,number | | | 1,1,1 | | | | | unique | -| EmptyList | list(string) | | | | | | "" | false | | -| EmptyListDupeOpts | list(string) | | | ["a"],["a"] | | | | | unique | -| EmptyMulti | tag-select | | | | | | "" | false | | -| EmptyOpts | string,number | | | 1,2,3 | | | "" | false | | -| EmptyRegex | string | | | | world | | | | regex error | -| EmptyMin | number | | | | 1-10 | | | | 1 < < 10 | -| EmptyMinOpt | number | | | 1,2,3 | 2-5 | | | | valid option | -| EmptyRegexOpt | string | | | "hello","goodbye" | goodbye | | | | valid option | -| EmptyRegexOk | string | | | | .* | | "" | false | | -| | | | | | | | | | | -| | Default Set | No inputs | | | | | | | | -| NumDef | number | | 5 | | | | 5 | true | | -| NumDefVal | number | | 5 | | 3-7 | | 5 | true | | -| NumDefInv | number | | 5 | | 10- | | | | 10 < 5 < 0 | -| NumDefOpts | number | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | -| NumDefNotOpts | number | | 5 | 1,3,7,9 | 2-6 | | | | valid option | -| NumDefInvOpt | number | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | -| NumDefNotNum | number | | a | | | | | | type "number" | -| NumDefOptsNotNum | number | | 1 | 1,a,2 | | | | | type "number" | -| | | | | | | | | | | -| StrDef | string | | hello | | | | hello | true | | -| StrDefInv | string | | hello | | world | | | | regex error | -| StrDefOpts | string | | a | a,b,c | | | a | true | | -| StrDefNotOpts | string | | a | b,c,d | | | | | valid option | -| StrDefValOpts | string | | a | a,b,c,d,e,f | [a-c] | | a | true | | -| StrDefInvOpt | string | | d | a,b,c,d,e,f | [a-c] | | | | regex error | -| | | | | | | | | | | -| LStrDef | list(string) | | ["a"] | | | | ["a"] | true | | -| LStrDefOpts | list(string) | | ["a"] | ["a"], ["b"] | | | ["a"] | true | | -| LStrDefNotOpts | list(string) | | ["a"] | ["b"], ["c"] | | | | | valid option | -| | | | | | | | | | | -| MulDef | tag-select | | ["a"] | | | | ["a"] | true | | -| MulDefOpts | multi-select | | ["a"] | a,b | | | ["a"] | true | | -| MulDefNotOpts | multi-select | | ["a"] | b,c | | | | | valid option | -| | | | | | | | | | | -| | Input Vals | | | | | | | | | -| NumIns | number | 3 | | | | | 3 | false | | -| NumInsOptsNaN | number | 3 | 5 | a,1,2,3,4,5 | 1-3 | | | | type "number" | -| NumInsNotNum | number | a | | | | | | | type "number" | -| NumInsNotNumInv | number | a | | | 1-3 | | | | 1 < a < 3 | -| NumInsDef | number | 3 | 5 | | | | 3 | true | | -| NumIns/DefInv | number | 3 | 5 | | 1-3 | | 3 | true | | -| NumIns=DefInv | number | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | -| NumInsOpts | number | 3 | 5 | 1,2,3,4,5 | 1-3 | | 3 | true | | -| NumInsNotOptsVal | number | 3 | 5 | 1,2,4,5 | 1-3 | | | | valid option | -| NumInsNotOptsInv | number | 3 | 5 | 1,2,4,5 | 1-2 | | | true | valid option | -| NumInsNotOpts | number | 3 | 5 | 1,2,4,5 | | | | | valid option | -| NumInsNotOpts/NoDef | number | 3 | | 1,2,4,5 | | | | | valid option | -| | | | | | | | | | | -| StrIns | string | c | | | | | c | false | | -| StrInsDupeOpts | string | c | | a,b,c,c | | | | | unique | -| StrInsDef | string | c | e | | | | c | true | | -| StrIns/DefInv | string | c | e | | [a-c] | | c | true | | -| StrIns=DefInv | string | e | e | | [a-c] | | | | regex error | -| StrInsOpts | string | c | e | a,b,c,d,e | [a-c] | | c | true | | -| StrInsNotOptsVal | string | c | e | a,b,d,e | [a-c] | | | | valid option | -| StrInsNotOptsInv | string | c | e | a,b,d,e | [a-b] | | | | valid option | -| StrInsNotOpts | string | c | e | a,b,d,e | | | | | valid option | -| StrInsNotOpts/NoDef | string | c | | a,b,d,e | | | | | valid option | -| StrInsBadVal | string | c | | a,b,c,d,e | 1-10 | | | | min cannot | -| | | | | | | | | | | -| | list(string) | | | | | | | | | -| LStrIns | list(string) | ["c"] | | | | | ["c"] | false | | -| LStrInsNotList | list(string) | c | | | | | | | list of strings | -| LStrInsDef | list(string) | ["c"] | ["e"] | | | | ["c"] | true | | -| LStrIns/DefInv | list(string) | ["c"] | ["e"] | | [a-c] | | | | regex cannot | -| LStrInsOpts | list(string) | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | -| LStrInsNotOpts | list(string) | ["c"] | ["e"] | ["d"],["e"] | | | | | valid option | -| LStrInsNotOpts/NoDef | list(string) | ["c"] | | ["d"],["e"] | | | | | valid option | -| | | | | | | | | | | -| MulInsOpts | multi-select | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | -| MulInsNotListOpts | multi-select | c | ["e"] | c,d,e | | | | | json encoded | -| MulInsNotOpts | multi-select | ["c"] | ["e"] | d,e | | | | | valid option | -| MulInsNotOpts/NoDef | multi-select | ["c"] | | d,e | | | | | valid option | -| MulInsInvOpts | multi-select | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file +| Name | Type | Previous | Input | Default | Options | Validation | -> | Output | Optional | ErrorCreate | +|----------------------|---------------|----------|-----------|---------|-------------------|------------|----|--------|----------|-----------------| +| | Empty Vals | | | | | | | | | | +| Empty | string,number | | | | | | | "" | false | | +| EmptyDupeOps | string,number | | | | 1,1,1 | | | | | unique | +| EmptyList | list(string) | | | | | | | "" | false | | +| EmptyListDupeOpts | list(string) | | | | ["a"],["a"] | | | | | unique | +| EmptyMulti | tag-select | | | | | | | "" | false | | +| EmptyOpts | string,number | | | | 1,2,3 | | | "" | false | | +| EmptyRegex | string | | | | | world | | | | regex error | +| EmptyMin | number | | | | | 1-10 | | | | 1 < < 10 | +| EmptyMinOpt | number | | | | 1,2,3 | 2-5 | | | | valid option | +| EmptyRegexOpt | string | | | | "hello","goodbye" | goodbye | | | | valid option | +| EmptyRegexOk | string | | | | | .* | | "" | false | | +| | | | | | | | | | | | +| | Default Set | | No inputs | | | | | | | | +| NumDef | number | | | 5 | | | | 5 | true | | +| NumDefVal | number | | | 5 | | 3-7 | | 5 | true | | +| NumDefInv | number | | | 5 | | 10- | | | | 10 < 5 < 0 | +| NumDefOpts | number | | | 5 | 1,3,5,7 | 2-6 | | 5 | true | | +| NumDefNotOpts | number | | | 5 | 1,3,7,9 | 2-6 | | | | valid option | +| NumDefInvOpt | number | | | 5 | 1,3,5,7 | 6-10 | | | | 6 < 5 < 10 | +| NumDefNotNum | number | | | a | | | | | | type "number" | +| NumDefOptsNotNum | number | | | 1 | 1,a,2 | | | | | type "number" | +| NumDefInc | number | 4 | | 5 | | increasing | | 5 | true | | +| NumDefIncBad | number | 6 | | 5 | | increasing | | | | greater | +| NumDefDec | number | 6 | | 5 | | decreasing | | 5 | true | | +| NumDefDecBad | number | 4 | | 5 | | decreasing | | | | lower | +| NumDefDecEq | number | 5 | | 5 | | decreasing | | 5 | true | | +| NumDefIncEq | number | 5 | | 5 | | increasing | | 5 | true | | +| NumDefIncNaN | number | a | | 5 | | increasing | | 5 | true | | +| NumDefDecNaN | number | b | | 5 | | decreasing | | 5 | true | | +| | | | | | | | | | | | +| StrDef | string | | | hello | | | | hello | true | | +| StrMonotonicity | string | | | hello | | increasing | | | | monotonic | +| StrDefInv | string | | | hello | | world | | | | regex error | +| StrDefOpts | string | | | a | a,b,c | | | a | true | | +| StrDefNotOpts | string | | | a | b,c,d | | | | | valid option | +| StrDefValOpts | string | | | a | a,b,c,d,e,f | [a-c] | | a | true | | +| StrDefInvOpt | string | | | d | a,b,c,d,e,f | [a-c] | | | | regex error | +| | | | | | | | | | | | +| LStrDef | list(string) | | | ["a"] | | | | ["a"] | true | | +| LStrDefOpts | list(string) | | | ["a"] | ["a"], ["b"] | | | ["a"] | true | | +| LStrDefNotOpts | list(string) | | | ["a"] | ["b"], ["c"] | | | | | valid option | +| | | | | | | | | | | | +| MulDef | tag-select | | | ["a"] | | | | ["a"] | true | | +| MulDefOpts | multi-select | | | ["a"] | a,b | | | ["a"] | true | | +| MulDefNotOpts | multi-select | | | ["a"] | b,c | | | | | valid option | +| | | | | | | | | | | | +| | Input Vals | | | | | | | | | | +| NumIns | number | | 3 | | | | | 3 | false | | +| NumInsOptsNaN | number | | 3 | 5 | a,1,2,3,4,5 | 1-3 | | | | type "number" | +| NumInsNotNum | number | | a | | | | | | | type "number" | +| NumInsNotNumInv | number | | a | | | 1-3 | | | | 1 < a < 3 | +| NumInsDef | number | | 3 | 5 | | | | 3 | true | | +| NumIns/DefInv | number | | 3 | 5 | | 1-3 | | 3 | true | | +| NumIns=DefInv | number | | 5 | 5 | | 1-3 | | | | 1 < 5 < 3 | +| NumInsOpts | number | | 3 | 5 | 1,2,3,4,5 | 1-3 | | 3 | true | | +| NumInsNotOptsVal | number | | 3 | 5 | 1,2,4,5 | 1-3 | | | | valid option | +| NumInsNotOptsInv | number | | 3 | 5 | 1,2,4,5 | 1-2 | | | true | valid option | +| NumInsNotOpts | number | | 3 | 5 | 1,2,4,5 | | | | | valid option | +| NumInsNotOpts/NoDef | number | | 3 | | 1,2,4,5 | | | | | valid option | +| NumInsInc | number | 4 | 5 | 3 | | increasing | | 5 | true | | +| NumInsIncBad | number | 6 | 5 | 7 | | increasing | | | | greater | +| NumInsDec | number | 6 | 5 | 7 | | decreasing | | 5 | true | | +| NumInsDecBad | number | 4 | 5 | 3 | | decreasing | | | | lower | +| NumInsDecEq | number | 5 | 5 | 5 | | decreasing | | 5 | true | | +| NumInsIncEq | number | 5 | 5 | 5 | | increasing | | 5 | true | | +| | | | | | | | | | | | +| StrIns | string | | c | | | | | c | false | | +| StrInsDupeOpts | string | | c | | a,b,c,c | | | | | unique | +| StrInsDef | string | | c | e | | | | c | true | | +| StrIns/DefInv | string | | c | e | | [a-c] | | c | true | | +| StrIns=DefInv | string | | e | e | | [a-c] | | | | regex error | +| StrInsOpts | string | | c | e | a,b,c,d,e | [a-c] | | c | true | | +| StrInsNotOptsVal | string | | c | e | a,b,d,e | [a-c] | | | | valid option | +| StrInsNotOptsInv | string | | c | e | a,b,d,e | [a-b] | | | | valid option | +| StrInsNotOpts | string | | c | e | a,b,d,e | | | | | valid option | +| StrInsNotOpts/NoDef | string | | c | | a,b,d,e | | | | | valid option | +| StrInsBadVal | string | | c | | a,b,c,d,e | 1-10 | | | | min cannot | +| | | | | | | | | | | | +| | list(string) | | | | | | | | | | +| LStrIns | list(string) | | ["c"] | | | | | ["c"] | false | | +| LStrInsNotList | list(string) | | c | | | | | | | list of strings | +| LStrInsDef | list(string) | | ["c"] | ["e"] | | | | ["c"] | true | | +| LStrIns/DefInv | list(string) | | ["c"] | ["e"] | | [a-c] | | | | regex cannot | +| LStrInsOpts | list(string) | | ["c"] | ["e"] | ["c"],["d"],["e"] | | | ["c"] | true | | +| LStrInsNotOpts | list(string) | | ["c"] | ["e"] | ["d"],["e"] | | | | | valid option | +| LStrInsNotOpts/NoDef | list(string) | | ["c"] | | ["d"],["e"] | | | | | valid option | +| | | | | | | | | | | | +| MulInsOpts | multi-select | | ["c"] | ["e"] | c,d,e | | | ["c"] | true | | +| MulInsNotListOpts | multi-select | | c | ["e"] | c,d,e | | | | | json encoded | +| MulInsNotOpts | multi-select | | ["c"] | ["e"] | d,e | | | | | valid option | +| MulInsNotOpts/NoDef | multi-select | | ["c"] | | d,e | | | | | valid option | +| MulInsInvOpts | multi-select | | ["c"] | ["e"] | c,d,e | [a-c] | | | | regex cannot | \ No newline at end of file From 4126ff41a540cd3c34dbf034fa1e4b269f38da70 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Fri, 9 May 2025 09:41:58 +0200 Subject: [PATCH 168/173] docs: link to additional documentation for prebuilt workspaces (#395) * docs: link to additional documentation for prebuilt workspaces * improve wording --- docs/data-sources/workspace_preset.md | 6 +++--- provider/workspace_preset.go | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index edd61f18..14e235f9 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -3,12 +3,12 @@ page_title: "coder_workspace_preset Data Source - terraform-provider-coder" subcategory: "" description: |- - Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace. + Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are defined by the template but not defined by the preset will still be configurable when creating a workspace. --- # coder_workspace_preset (Data Source) -Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace. +Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are defined by the template but not defined by the preset will still be configurable when creating a workspace. ## Example Usage @@ -39,7 +39,7 @@ data "coder_workspace_preset" "example" { ### Optional - `parameters` (Map of String) Workspace parameters that will be set by the workspace preset. For simple templates that only need prebuilds, you may define a preset with zero parameters. Because workspace parameters may change between Coder template versions, preset parameters are allowed to define values for parameters that do not exist in the current template version. -- `prebuilds` (Block Set, Max: 1) Prebuilt workspace configuration related to this workspace preset. Coder will build and maintain workspaces in reserve based on this configuration. When a user creates a new workspace using a preset, they will be assigned a prebuilt workspace, instead of waiting for a new workspace to build. (see [below for nested schema](#nestedblock--prebuilds)) +- `prebuilds` (Block Set, Max: 1) Configuration for prebuilt workspaces associated with this preset. Coder will maintain a pool of standby workspaces based on this configuration. When a user creates a workspace using this preset, they are assigned a prebuilt workspace instead of waiting for a new one to build. See prebuilt workspace documentation [here](https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces.md) (see [below for nested schema](#nestedblock--prebuilds)) ### Read-Only diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 2fab0b8a..78466c10 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -28,7 +28,8 @@ func workspacePresetDataSource() *schema.Resource { return &schema.Resource{ SchemaVersion: 1, - Description: "Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are not defined by the preset will still be configurable when creating a workspace.", + Description: "Use this data source to predefine common configurations for coder workspaces. Users will have the option to select a defined preset, which will automatically apply the selected configuration. Any parameters defined in the preset will be applied to the workspace. Parameters that are defined by the template but not defined by the preset will still be configurable when creating a workspace.", + ReadContext: func(ctx context.Context, rd *schema.ResourceData, i interface{}) diag.Diagnostics { var preset WorkspacePreset err := mapstructure.Decode(struct { @@ -68,7 +69,7 @@ func workspacePresetDataSource() *schema.Resource { }, "prebuilds": { Type: schema.TypeSet, - Description: "Prebuilt workspace configuration related to this workspace preset. Coder will build and maintain workspaces in reserve based on this configuration. When a user creates a new workspace using a preset, they will be assigned a prebuilt workspace, instead of waiting for a new workspace to build.", + Description: "Configuration for prebuilt workspaces associated with this preset. Coder will maintain a pool of standby workspaces based on this configuration. When a user creates a workspace using this preset, they are assigned a prebuilt workspace instead of waiting for a new one to build. See prebuilt workspace documentation [here](https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces.md)", Optional: true, MaxItems: 1, Elem: &schema.Resource{ From 50ed1c120bb89a31c90881522fde10929f8a0004 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Fri, 9 May 2025 18:44:08 +0200 Subject: [PATCH 169/173] feat: expose `is_prebuild_claim` attribute (#396) * feat: expose is_prebuild_claim attribute Signed-off-by: Danny Kopping * fix: string comparison hardening Signed-off-by: Danny Kopping --------- Signed-off-by: Danny Kopping --- docs/data-sources/workspace.md | 1 + provider/workspace.go | 44 +++++++++++- provider/workspace_test.go | 120 +++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 29fd9179..4dacdfc3 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -70,6 +70,7 @@ resource "docker_container" "workspace" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `is_prebuild` (Boolean) Similar to `prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false. +- `is_prebuild_claim` (Boolean) Indicates whether a prebuilt workspace has just been claimed and this is the first `apply` after that occurrence. - `name` (String) Name of the workspace. - `prebuild_count` (Number) A computed count, equal to 1 if the workspace is a currently unassigned prebuild. Use this to conditionally act on the status of a prebuild. Actions that do not require user identity can be taken when this value is set to 1. Actions that should only be taken once the workspace has been assigned to a user may be taken when this value is set to 0. - `start_count` (Number) A computed count based on `transition` state. If `start`, count will equal 1. diff --git a/provider/workspace.go b/provider/workspace.go index c477fad6..58100a88 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -4,6 +4,7 @@ import ( "context" "reflect" "strconv" + "strings" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -30,10 +31,23 @@ func workspaceDataSource() *schema.Resource { if isPrebuiltWorkspace() { _ = rd.Set("prebuild_count", 1) _ = rd.Set("is_prebuild", true) + + // A claim can only take place AFTER a prebuild, so it's not logically consistent to have this set to any other value. + _ = rd.Set("is_prebuild_claim", false) } else { _ = rd.Set("prebuild_count", 0) _ = rd.Set("is_prebuild", false) } + if isPrebuiltWorkspaceClaim() { + // Indicate that a prebuild claim has taken place. + _ = rd.Set("is_prebuild_claim", true) + + // A claim can only take place AFTER a prebuild, so it's not logically consistent to have these set to any other values. + _ = rd.Set("prebuild_count", 0) + _ = rd.Set("is_prebuild", false) + } else { + _ = rd.Set("is_prebuild_claim", false) + } name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) @@ -116,6 +130,11 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Similar to `prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false.", }, + "is_prebuild_claim": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether a prebuilt workspace has just been claimed and this is the first `apply` after that occurrence.", + }, "name": { Type: schema.TypeString, Computed: true, @@ -142,7 +161,12 @@ func workspaceDataSource() *schema.Resource { // isPrebuiltWorkspace returns true if the workspace is an unclaimed prebuilt workspace. func isPrebuiltWorkspace() bool { - return helpers.OptionalEnv(IsPrebuildEnvironmentVariable()) == "true" + return strings.EqualFold(helpers.OptionalEnv(IsPrebuildEnvironmentVariable()), "true") +} + +// isPrebuiltWorkspaceClaim returns true if the workspace is a prebuilt workspace which has just been claimed. +func isPrebuiltWorkspaceClaim() bool { + return strings.EqualFold(helpers.OptionalEnv(IsPrebuildClaimEnvironmentVariable()), "true") } // IsPrebuildEnvironmentVariable returns the name of the environment variable that @@ -161,3 +185,21 @@ func isPrebuiltWorkspace() bool { func IsPrebuildEnvironmentVariable() string { return "CODER_WORKSPACE_IS_PREBUILD" } + +// IsPrebuildClaimEnvironmentVariable returns the name of the environment variable that +// indicates whether the workspace is a prebuilt workspace which has just been claimed, and this is the first Terraform +// apply after that occurrence. +// +// Knowing whether the workspace is a claimed prebuilt workspace allows template +// authors to conditionally execute code in the template based on whether the workspace +// has been assigned to a user or not. This allows identity specific configuration to +// be applied only after the workspace is claimed, while the rest of the workspace can +// be pre-configured. +// +// The value of this environment variable should be set to "true" if the workspace is prebuilt +// and it has just been claimed by a user. Any other values, including "false" +// and "" will be interpreted to mean that the workspace is not prebuilt, or was +// prebuilt but has not been claimed by a user. +func IsPrebuildClaimEnvironmentVariable() string { + return "CODER_WORKSPACE_IS_PREBUILD_CLAIM" +} diff --git a/provider/workspace_test.go b/provider/workspace_test.go index e82a1005..17dfabd2 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -4,6 +4,7 @@ import ( "regexp" "testing" + "github.com/coder/terraform-provider-coder/v2/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/stretchr/testify/assert" @@ -102,3 +103,122 @@ func TestWorkspace_MissingTemplateName(t *testing.T) { }}, }) } + +// TestWorkspace_PrebuildEnv validates that our handling of input environment variables is correct. +func TestWorkspace_PrebuildEnv(t *testing.T) { + cases := []struct { + name string + envs map[string]string + check func(state *terraform.State, resource *terraform.ResourceState) error + }{ + { + name: "unused", + envs: map[string]string{}, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "false", attribs["is_prebuild"]) + assert.Equal(t, "0", attribs["prebuild_count"]) + assert.Equal(t, "false", attribs["is_prebuild_claim"]) + return nil + }, + }, + { + name: "prebuild=true", + envs: map[string]string{ + provider.IsPrebuildEnvironmentVariable(): "true", + }, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "true", attribs["is_prebuild"]) + assert.Equal(t, "1", attribs["prebuild_count"]) + assert.Equal(t, "false", attribs["is_prebuild_claim"]) + return nil + }, + }, + { + name: "prebuild=false", + envs: map[string]string{ + provider.IsPrebuildEnvironmentVariable(): "false", + }, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "false", attribs["is_prebuild"]) + assert.Equal(t, "0", attribs["prebuild_count"]) + assert.Equal(t, "false", attribs["is_prebuild_claim"]) + return nil + }, + }, + { + name: "prebuild_claim=true", + envs: map[string]string{ + provider.IsPrebuildClaimEnvironmentVariable(): "true", + }, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "false", attribs["is_prebuild"]) + assert.Equal(t, "0", attribs["prebuild_count"]) + assert.Equal(t, "true", attribs["is_prebuild_claim"]) + return nil + }, + }, + { + name: "prebuild_claim=false", + envs: map[string]string{ + provider.IsPrebuildClaimEnvironmentVariable(): "false", + }, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "false", attribs["is_prebuild"]) + assert.Equal(t, "0", attribs["prebuild_count"]) + assert.Equal(t, "false", attribs["is_prebuild_claim"]) + return nil + }, + }, + { + // Should not ever happen, but let's ensure our defensive check is activated. We can't ever have both flags + // being true. + name: "prebuild=true,prebuild_claim=true", + envs: map[string]string{ + provider.IsPrebuildEnvironmentVariable(): "true", + provider.IsPrebuildClaimEnvironmentVariable(): "true", + }, + check: func(state *terraform.State, resource *terraform.ResourceState) error { + attribs := resource.Primary.Attributes + assert.Equal(t, "false", attribs["is_prebuild"]) + assert.Equal(t, "0", attribs["prebuild_count"]) + assert.Equal(t, "true", attribs["is_prebuild_claim"]) + return nil + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + for k, v := range tc.envs { + t.Setenv(k, v) + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` +provider "coder" { + url = "https://example.com:8080" +} +data "coder_workspace" "me" { +}`, + Check: func(state *terraform.State) error { + // Baseline checks + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + resource := state.Modules[0].Resources["data.coder_workspace.me"] + require.NotNil(t, resource) + + return tc.check(state, resource) + }, + }}, + }) + }) + } +} From 760b9fffa39ded6b1f2660fbf6ecb2746c801426 Mon Sep 17 00:00:00 2001 From: Danny Kopping Date: Mon, 12 May 2025 09:04:03 +0200 Subject: [PATCH 170/173] chore: add tag_sort option to goreleaser (#398) Choose more recently-created tag if multiple tags point to same ref Signed-off-by: Danny Kopping --- .goreleaser.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 658a715c..8b2c0012 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -60,3 +60,5 @@ changelog: use: github-native sort: asc abbrev: 0 +git: + tag_sort: -version:creatordate # if two tags reference the same commit, pick the latest one; see https://github.com/goreleaser/goreleaser/issues/4209 \ No newline at end of file From ff49ef5840f013950b47b20090ae7acdc35fc1a5 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 12 May 2025 07:53:13 -0500 Subject: [PATCH 171/173] test: add unit test to document behavior when no new value exists (#394) --- provider/testdata/parameter_table.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md index 6087460f..980a6d19 100644 --- a/provider/testdata/parameter_table.md +++ b/provider/testdata/parameter_table.md @@ -12,6 +12,8 @@ | EmptyMinOpt | number | | | | 1,2,3 | 2-5 | | | | valid option | | EmptyRegexOpt | string | | | | "hello","goodbye" | goodbye | | | | valid option | | EmptyRegexOk | string | | | | | .* | | "" | false | | +| EmptyInc | number | 4 | | | | increasing | | | | monotonicity | +| EmptyDec | number | 4 | | | | decreasing | | | | monotonicity | | | | | | | | | | | | | | | Default Set | | No inputs | | | | | | | | | NumDef | number | | | 5 | | | | 5 | true | | From 01334b626acc918967f0519759618dc86b6f0fb9 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 15 May 2025 15:33:50 +0100 Subject: [PATCH 172/173] feat(agent): add api_key_scope to control agent token permissions (#391) --- .gitignore | 3 + docs/resources/agent.md | 8 +- examples/resources/coder_agent/resource.tf | 7 +- flake.lock | 8 +- flake.nix | 6 +- provider/agent.go | 11 +++ provider/agent_test.go | 91 ++++++++++++++++++++++ 7 files changed, 121 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 4d5d5ad6..ff9f6a53 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ website/vendor # Binary terraform-provider-coder + +# direnv +.direnv diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 7c28b1f4..7df11e34 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -17,9 +17,10 @@ data "coder_workspace" "me" { } resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "/workspace" + os = "linux" + arch = "amd64" + dir = "/workspace" + api_key_scope = "all" display_apps { vscode = true vscode_insiders = false @@ -71,6 +72,7 @@ resource "kubernetes_pod" "dev" { ### Optional +- `api_key_scope` (String) Controls what API routes the agent token can access. Options: 'all' (full access) or 'no_user_data' (blocks /external-auth, /gitsshkey, and /gitauth routes) - `auth` (String) The authentication type the agent will use. Must be one of: `"token"`, `"google-instance-identity"`, `"aws-instance-identity"`, `"azure-instance-identity"`. - `connection_timeout` (Number) Time in seconds until the agent is marked as timed out when a connection with the server cannot be established. A value of zero never marks the agent as timed out. - `dir` (String) The starting directory when a user creates a shell session. Defaults to `"$HOME"`. diff --git a/examples/resources/coder_agent/resource.tf b/examples/resources/coder_agent/resource.tf index 6ccb07bf..7c219604 100644 --- a/examples/resources/coder_agent/resource.tf +++ b/examples/resources/coder_agent/resource.tf @@ -2,9 +2,10 @@ data "coder_workspace" "me" { } resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "/workspace" + os = "linux" + arch = "amd64" + dir = "/workspace" + api_key_scope = "all" display_apps { vscode = true vscode_insiders = false diff --git a/flake.lock b/flake.lock index d8033e14..ecf99d98 100644 --- a/flake.lock +++ b/flake.lock @@ -20,16 +20,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1714272655, - "narHash": "sha256-3/ghIWCve93ngkx5eNPdHIKJP/pMzSr5Wc4rNKE1wOc=", + "lastModified": 1746422338, + "narHash": "sha256-NTtKOTLQv6dPfRe00OGSywg37A1FYqldS6xiNmqBUYc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "12430e43bd9b81a6b4e79e64f87c624ade701eaf", + "rev": "5b35d248e9206c1f3baf8de6a7683fee126364aa", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.11", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } diff --git a/flake.nix b/flake.nix index 87719bf4..40ceb861 100644 --- a/flake.nix +++ b/flake.nix @@ -2,11 +2,11 @@ description = "Terraform provider for Coder"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, flake-utils, ... }: + outputs = { nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { @@ -21,7 +21,7 @@ name = "devShell"; buildInputs = with pkgs; [ terraform - go_1_20 + go_1_24 ]; }; } diff --git a/provider/agent.go b/provider/agent.go index ad264030..ebd8fff5 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -80,6 +80,17 @@ func agentResource() *schema.Resource { return nil }, Schema: map[string]*schema.Schema{ + "api_key_scope": { + Type: schema.TypeString, + Optional: true, + Default: "all", + ForceNew: true, + Description: "Controls what API routes the agent token can access. Options: 'all' (full access) or 'no_user_data' (blocks /external-auth, /gitsshkey, and /gitauth routes)", + ValidateFunc: validation.StringInSlice([]string{ + "all", + "no_user_data", + }, false), + }, "init_script": { Type: schema.TypeString, Computed: true, diff --git a/provider/agent_test.go b/provider/agent_test.go index a45ac86a..82e8691f 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -709,5 +709,96 @@ func TestAgent_DisplayApps(t *testing.T) { }}, }) }) +} + +// TestAgent_APIKeyScope tests valid states/transitions and invalid values for api_key_scope. +func TestAgent_APIKeyScope(t *testing.T) { + t.Parallel() + + t.Run("ValidTransitions", func(t *testing.T) { + t.Parallel() + + resourceName := "coder_agent.test_scope_valid" + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{ + // Step 1: Default value + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + # api_key_scope is omitted, should default to "default" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "all"), + ), + }, + // Step 2: Explicit "default" + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + api_key_scope = "all" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "all"), + ), + }, + // Step 3: Explicit "no_user_data" + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + api_key_scope = "no_user_data" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "no_user_data"), + ), + }, + }, + }) + }) + + t.Run("InvalidValue", func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{ + // Step 1: Invalid value check + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_invalid" { // Use unique name + os = "linux" + arch = "amd64" + api_key_scope = "invalid-scope" + } + `, + ExpectError: regexp.MustCompile(`expected api_key_scope to be one of \["all" "no_user_data"\], got invalid-scope`), + PlanOnly: true, + }, + }, + }) + }) } From ace4462675ffbab17e098dff330ce50ece20b7fe Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Sun, 18 May 2025 09:15:30 -0500 Subject: [PATCH 173/173] fix: allow dropdown form_type for boolean types (#397) * fix: allow dropdown form_type for boolean types * add dropdown boolean test --- provider/formtype.go | 2 +- provider/formtype_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/provider/formtype.go b/provider/formtype.go index 75d32c46..931179da 100644 --- a/provider/formtype.go +++ b/provider/formtype.go @@ -99,7 +99,7 @@ var formTypeTruthTable = map[OptionType]map[bool][]ParameterFormType{ false: {ParameterFormTypeInput, ParameterFormTypeSlider}, }, OptionTypeBoolean: { - true: {ParameterFormTypeRadio}, + true: {ParameterFormTypeRadio, ParameterFormTypeDropdown}, false: {ParameterFormTypeCheckbox, ParameterFormTypeSwitch}, }, OptionTypeListString: { diff --git a/provider/formtype_test.go b/provider/formtype_test.go index eaf7b587..2f3dff53 100644 --- a/provider/formtype_test.go +++ b/provider/formtype_test.go @@ -193,6 +193,11 @@ func TestValidateFormType(t *testing.T) { optionType: provider.OptionTypeBoolean, formType: provider.ParameterFormTypeRadio, }), + expectSameFormType(formTypeCheck{ + options: true, + optionType: provider.OptionTypeBoolean, + formType: provider.ParameterFormTypeDropdown, + }), expectSameFormType(formTypeCheck{ options: false, optionType: provider.OptionTypeBoolean,