Skip to content

Commit

Permalink
Merge branch 'master' into SCALRCORE-33203
Browse files Browse the repository at this point in the history
  • Loading branch information
petroprotsakh committed Feb 5, 2025
2 parents 8e56427 + 4918ab0 commit 674d210
Show file tree
Hide file tree
Showing 16 changed files with 410 additions and 214 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
### Changed

- `scalr_workspace`: deleted attribute `terragrunt_version` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390))
- `scalr_workspace`: deleted attribute `terragrunt_use_run_all` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390))
- `scalr_workspace`: added attribute `terragrunt` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390))
- `scalr_agent_pool_token`: attribute `description` is now optional ([#392](https://github.com/Scalr/terraform-provider-scalr/pull/392))

- `scalr_environment` and `data.scalr_environment`: new attribute `mask_sensitive_output` ([#389](https://github.com/Scalr/terraform-provider-scalr/pull/389))

Expand Down
13 changes: 11 additions & 2 deletions docs/data-sources/workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ data "scalr_workspace" "example2" {
- `vcs_provider_id` (String) The identifier of a VCS provider in the format `vcs-<RANDOM STRING>`.
- `vcs_repo` (List of Object) If a workspace is linked to a VCS repository this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--vcs_repo))
- `working_directory` (String) A relative path that Terraform will execute within.
- `terragrunt_version` (String) The version of Terragrunt the workspace performs runs on.
- `terragrunt_use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`.
- `terragrunt` (List of Object) If a workspace is linked to a Terragrunt configuration this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--terragrunt))

<a id="nestedatt--created_by"></a>
### Nested Schema for `created_by`
Expand Down Expand Up @@ -95,3 +94,13 @@ Read-Only:
- `identifier` (String) The reference to the VCS repository in the format `:org/:repo`, this refers to the organization and repository in your VCS provider.
- `ingress_submodules` (Boolean) Designates whether to clone git submodules of the VCS repository.
- `path` (String) Path within the repo, if any.


<a id="nestedatt--terragrunt"></a>
### Nested Schema for `terragrunt`

Read-Only:

- `version` (String) The version of Terragrunt used for this workspace.
- `use_run_all` (Boolean) Boolean indicates if Terragrunt will use `run-all` command.
- `include_external_dependencies` (Boolean) Boolean indicates if Terragrunt will include external dependencies.
5 changes: 4 additions & 1 deletion docs/resources/agent_pool_token.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ order: 4
---
## Resource: scalr_agent_pool_token

Manage the state of agent pool's tokens in Scalr. Create, update and destroy.
Manage the state of agent pool's tokens in Scalr.

## Example Usage

Expand All @@ -25,6 +25,9 @@ resource "scalr_agent_pool_token" "default" {
### Required

- `agent_pool_id` (String) ID of the agent pool.

### Optional

- `description` (String) Description of the token.

### Read-Only
Expand Down
16 changes: 14 additions & 2 deletions docs/resources/workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ resource "scalr_workspace" "example-b" {
- `ssh_key_id` (String) The identifier of the SSH key to use for the workspace.
- `tag_ids` (Set of String) List of tag IDs associated with the workspace.
- `terraform_version` (String) The version of Terraform to use for this workspace. Defaults to the latest available version.
- `terragrunt_use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`.
- `terragrunt_version` (String) The version of Terragrunt the workspace performs runs on.
- `terragrunt` (Block List) Settings for the workspace's Terragrunt configuration. (see [below for nested schema](#nestedblock--terragrunt))
- `type` (String) The type of the Scalr Workspace environment, available options: `production`, `staging`, `testing`, `development`, `unmapped`.
- `var_files` (List of String) A list of paths to the `.tfvars` file(s) to be used as part of the workspace configuration.
- `vcs_provider_id` (String) ID of VCS provider - required if vcs-repo present and vice versa, in the format `vcs-<RANDOM STRING>`.
Expand Down Expand Up @@ -206,6 +205,19 @@ Optional:
- `alias` (String) The alias of provider configuration.


<a id="nestedblock--terragrunt"></a>
### Nested Schema for `terragrunt`

Required:

- `version` (String) The version of Terragrunt the workspace performs runs on.

Optional:

- `include_external_dependencies` (Boolean) Indicates whether the workspace includes external dependencies.
- `use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`.


<a id="nestedblock--vcs_repo"></a>
### Nested Schema for `vcs_repo`

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0
github.com/hashicorp/terraform-plugin-testing v1.11.0
github.com/hashicorp/terraform-svchost v0.1.1
github.com/scalr/go-scalr v0.0.0-20250128143817-6fe2e9169f9e
github.com/scalr/go-scalr v0.0.0-20250205142310-cb315ca4c0ec
)

require (
Expand Down Expand Up @@ -47,7 +47,7 @@ require (
github.com/hashicorp/terraform-exec v0.21.0 // indirect
github.com/hashicorp/terraform-json v0.23.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTV
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/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
Expand Down Expand Up @@ -201,8 +201,8 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/scalr/go-scalr v0.0.0-20250128143817-6fe2e9169f9e h1:QPmUbku+pt3EMxCevyTZFZCXDYMkQQd0VQxRd5adWpA=
github.com/scalr/go-scalr v0.0.0-20250128143817-6fe2e9169f9e/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE=
github.com/scalr/go-scalr v0.0.0-20250205142310-cb315ca4c0ec h1:/rVxuNZVHple6gIJyemO5YsN+fYFXL7aNpK5b+0/wzc=
github.com/scalr/go-scalr v0.0.0-20250205142310-cb315ca4c0ec/go.mod h1:PKuZ6tEH/QfPk10pLtFCN7yYqYQ3przx/Yut1qbK48Q=
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/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
Expand Down
201 changes: 201 additions & 0 deletions internal/provider/agent_pool_token_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package provider

import (
"context"
"errors"

"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/scalr/go-scalr"

"github.com/scalr/terraform-provider-scalr/internal/framework"
)

// Compile-time interface checks
var (
_ resource.Resource = &agentPoolTokenResource{}
_ resource.ResourceWithConfigure = &agentPoolTokenResource{}
)

func newAgentPoolTokenResource() resource.Resource {
return &agentPoolTokenResource{}
}

// agentPoolTokenResource defines the resource implementation.
type agentPoolTokenResource struct {
framework.ResourceWithScalrClient
}

// agentPoolTokenResourceModel describes the resource data model.
type agentPoolTokenResourceModel struct {
Id types.String `tfsdk:"id"`
Description types.String `tfsdk:"description"`
AgentPoolID types.String `tfsdk:"agent_pool_id"`
Token types.String `tfsdk:"token"`
}

func (r *agentPoolTokenResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_agent_pool_token"
}

func (r *agentPoolTokenResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Manage the state of agent pool's tokens in Scalr.",

Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "The ID of this resource.",
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"description": schema.StringAttribute{
MarkdownDescription: "Description of the token.",
Optional: true,
Computed: true,
Default: stringdefault.StaticString(""),
},
"agent_pool_id": schema.StringAttribute{
MarkdownDescription: "ID of the agent pool.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"token": schema.StringAttribute{
MarkdownDescription: "The token of the agent pool.",
Computed: true,
Sensitive: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
},
}
}

func (r *agentPoolTokenResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var plan agentPoolTokenResourceModel

// Read plan data
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

opts := scalr.AccessTokenCreateOptions{
Description: plan.Description.ValueStringPointer(),
}

agentPoolToken, err := r.Client.AgentPoolTokens.Create(ctx, plan.AgentPoolID.ValueString(), opts)
if err != nil {
resp.Diagnostics.AddError("Error creating agent_pool_token", err.Error())
return
}

plan.Id = types.StringValue(agentPoolToken.ID)
plan.Description = types.StringValue(agentPoolToken.Description)
plan.Token = types.StringValue(agentPoolToken.Token)

// Set state to fully populated data
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
if resp.Diagnostics.HasError() {
return
}
}

func (r *agentPoolTokenResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state agentPoolTokenResourceModel

resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

opts := scalr.AccessTokenListOptions{}

for {
tokensList, err := r.Client.AgentPoolTokens.List(ctx, state.AgentPoolID.ValueString(), opts)

if err != nil {
if errors.Is(err, scalr.ErrResourceNotFound) {
resp.State.RemoveResource(ctx)
return
}
resp.Diagnostics.AddError("Error retrieving agent_pool_token", err.Error())
return
}

for _, t := range tokensList.Items {
if t.ID == state.Id.ValueString() {
state.Description = types.StringValue(t.Description)

// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
return
}
}

// Exit the loop when we've seen all pages.
if tokensList.CurrentPage >= tokensList.TotalPages {
break
}

// Update the page number to get the next page.
opts.PageNumber = tokensList.NextPage
}

// The token has been deleted
resp.State.RemoveResource(ctx)
}

func (r *agentPoolTokenResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan agentPoolTokenResourceModel

// Read plan data
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

opts := scalr.AccessTokenUpdateOptions{
Description: plan.Description.ValueStringPointer(),
}

// Update existing resource
agentPoolToken, err := r.Client.AccessTokens.Update(ctx, plan.Id.ValueString(), opts)
if err != nil {
resp.Diagnostics.AddError("Error updating agent_pool_token", err.Error())
return
}

// Overwrite attributes with refreshed values
plan.Description = types.StringValue(agentPoolToken.Description)

// Set refreshed state
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
if resp.Diagnostics.HasError() {
return
}
}

func (r *agentPoolTokenResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state agentPoolTokenResourceModel

// Get current state
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

err := r.Client.AccessTokens.Delete(ctx, state.Id.ValueString())
if err != nil && !errors.Is(err, scalr.ErrResourceNotFound) {
resp.Diagnostics.AddError("Error deleting agent_pool_token", err.Error())
return
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/scalr/go-scalr"
)
Expand Down Expand Up @@ -67,6 +68,42 @@ func TestAccScalrAgentPoolToken_update(t *testing.T) {
})
}

func TestAccScalrAgentPoolToken_UpgradeFromSDK(t *testing.T) {
var pool scalr.AgentPool
if isAccTest() {
pool = createPool(t)
defer deletePool(t, pool)
}

resource.Test(t, resource.TestCase{
Steps: []resource.TestStep{
{
ExternalProviders: map[string]resource.ExternalProvider{
"scalr": {
Source: "registry.scalr.io/scalr/scalr",
VersionConstraint: "<=2.4.0",
},
},
Config: testAccScalrAgentPoolTokenBasic(pool),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("scalr_agent_pool_token.test", "description", "agent_pool_token-test"),
resource.TestCheckResourceAttr("scalr_agent_pool_token.test", "agent_pool_id", pool.ID),
resource.TestCheckResourceAttrSet("scalr_agent_pool_token.test", "token"),
),
},
{
ProtoV5ProviderFactories: protoV5ProviderFactories(t),
Config: testAccScalrAgentPoolTokenBasic(pool),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(),
},
},
},
},
})
}

func testAccCheckScalrAgentPoolTokenExists(resId string, pool scalr.AgentPool, token *scalr.AccessToken) resource.TestCheckFunc {
return func(s *terraform.State) error {
scalrClient := testAccProviderSDK.Meta().(*scalr.Client)
Expand Down
Loading

0 comments on commit 674d210

Please sign in to comment.