Skip to content

Commit

Permalink
feat: Add workers data source (#818)
Browse files Browse the repository at this point in the history
  • Loading branch information
denys-octopus authored Nov 19, 2024
1 parent 6d9700f commit ee600ff
Show file tree
Hide file tree
Showing 6 changed files with 459 additions and 0 deletions.
70 changes: 70 additions & 0 deletions docs/data-sources/workers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "octopusdeploy_workers Data Source - terraform-provider-octopusdeploy"
subcategory: ""
description: |-
Provides information about existing workers.
---

# octopusdeploy_workers (Data Source)

Provides information about existing workers.

## Example Usage

```terraform
data "octopusdeploy_workers" "example" {
communication_styles = ["TentaclePassive"]
health_statuses = ["Unavailable"]
ids = ["Workers-123"]
name = "Exact name"
partial_name = "Test"
skip = 5
take = 100
is_disabled = true
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `communication_styles` (List of String) A filter to search by communication styles
- `health_statuses` (List of String) A filter to search by health statuses
- `ids` (List of String) A filter to search by a list of IDs.
- `is_disabled` (Boolean)
- `name` (String) The name of this resource.
- `partial_name` (String) A filter to search by a partial name.
- `skip` (Number) A filter to specify the number of items to skip in the response.
- `space_id` (String) The space ID associated with this workers.
- `take` (Number) A filter to specify the number of items to take (or return) in the response.

### Read-Only

- `id` (String) The unique ID for this resource.
- `workers` (Attributes List) (see [below for nested schema](#nestedatt--workers))

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

Read-Only:

- `account_id` (String)
- `communication_style` (String)
- `dotnet_platform` (String)
- `fingerprint` (String)
- `health_status` (String)
- `host` (String)
- `id` (String) The unique ID for this resource.
- `is_disabled` (Boolean)
- `machine_policy_id` (String)
- `name` (String) The name of this resource.
- `port` (Number)
- `proxy_id` (String)
- `space_id` (String) The space ID associated with this workers.
- `thumbprint` (String)
- `uri` (String)
- `worker_pool_ids` (List of String)


10 changes: 10 additions & 0 deletions examples/data-sources/octopusdeploy_workers/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
data "octopusdeploy_workers" "example" {
communication_styles = ["TentaclePassive"]
health_statuses = ["Unavailable"]
ids = ["Workers-123"]
name = "Exact name"
partial_name = "Test"
skip = 5
take = 100
is_disabled = true
}
72 changes: 72 additions & 0 deletions octopusdeploy_framework/datasource_workers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package octopusdeploy_framework

import (
"context"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/workers"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/schemas"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/types"
"time"
)

type workersDataSource struct {
*Config
}

func NewWorkersDataSource() datasource.DataSource {
return &workersDataSource{}
}

func (*workersDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = util.GetTypeName("workers")
}

func (e *workersDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
e.Config = DataSourceConfiguration(req, resp)
}

func (*workersDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schemas.WorkersSchema{}.GetDatasourceSchema()
}

func (e *workersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var err error
var data schemas.WorkersDataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

query := machines.WorkersQuery{
Name: data.Name.ValueString(),
IDs: util.GetIds(data.IDs),
PartialName: data.PartialName.ValueString(),
Skip: util.GetNumber(data.Skip),
Take: util.GetNumber(data.Take),
CommunicationStyles: util.ExpandStringList(data.CommunicationStyle),
HealthStatuses: util.ExpandStringList(data.HealthStatuses),
IsDisabled: data.IsDisabled.ValueBool(),
}

util.DatasourceReading(ctx, "workers", query)

existingWorkers, err := workers.Get(e.Client, data.SpaceID.ValueString(), query)
if err != nil {
resp.Diagnostics.AddError("unable to load workers", err.Error())
return
}

util.DatasourceResultCount(ctx, "workers", len(existingWorkers.Items))

resources := []interface{}{}
for _, worker := range existingWorkers.Items {
resources = append(resources, schemas.FlattenWorker(worker))
}

data.Workers, _ = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: schemas.WorkerObjectType()}, resources)
data.ID = types.StringValue("Workers " + time.Now().UTC().String())

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
130 changes: 130 additions & 0 deletions octopusdeploy_framework/datasource_workers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package octopusdeploy_framework

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)

func TestAccDataSourceWorkers(t *testing.T) {
localName := acctest.RandStringFromCharSet(50, acctest.CharSetAlpha)
prefix := fmt.Sprintf("data.octopusdeploy_workers.%s", localName)
sshFilter := `communication_styles = ["Ssh"]`
listeningFilter := `communication_styles = ["TentaclePassive"]`

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: ProtoV6ProviderFactories(),
PreCheck: func() { TestAccPreCheck(t) },
Steps: []resource.TestStep{
{
Config: configTestAccDataSourceWorkerResources(localName, ""),
},
{
Config: configTestAccDataSourceWorkerResources(localName, ""),
Check: testAssertDataSourceWorkersEmpty(prefix),
},
{
Config: configTestAccDataSourceWorkerResources(localName, sshFilter),
Check: testAssertDataSourceSSHWorkers(prefix),
},
{
Config: configTestAccDataSourceWorkerResources(localName, listeningFilter),
Check: testAssertDataSourceListeningWorkers(prefix),
},
},
})
}

func testAssertDataSourceWorkersEmpty(prefix string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
testAssertWorkersDataSourceID(prefix),
resource.TestCheckResourceAttr(prefix, "workers.#", "2"),
)
}

func testAssertDataSourceSSHWorkers(prefix string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
testAssertWorkersDataSourceID(prefix),
resource.TestCheckResourceAttr(prefix, "workers.#", "1"),
resource.TestCheckResourceAttr(prefix, "workers.0.name", "First SSH worker"),
resource.TestCheckResourceAttr(prefix, "workers.0.host", "test.domain"),
resource.TestCheckResourceAttr(prefix, "workers.0.port", "4201"),
resource.TestCheckResourceAttr(prefix, "workers.0.fingerprint", "SHA256: 1234abcdef56789"),
resource.TestCheckResourceAttr(prefix, "workers.0.dotnet_platform", "linux-x64"),
)
}

func testAssertDataSourceListeningWorkers(prefix string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
testAssertWorkersDataSourceID(prefix),
resource.TestCheckResourceAttr(prefix, "workers.#", "1"),
resource.TestCheckResourceAttr(prefix, "workers.0.name", "Second listening worker"),
resource.TestCheckResourceAttr(prefix, "workers.0.uri", "https://domain.test/"),
resource.TestCheckResourceAttr(prefix, "workers.0.thumbprint", "abcdef"),
)
}

func testAssertWorkersDataSourceID(prefix string) resource.TestCheckFunc {
return func(s *terraform.State) error {
all := s.RootModule().Resources
dataSource, ok := all[prefix]
if !ok {
return fmt.Errorf("cannot find Workers data source: %s", prefix)
}

if dataSource.Primary.ID == "" {
return fmt.Errorf("snapshot Workers source ID not set")
}
return nil
}
}

func configTestAccDataSourceWorkerResources(localName string, dataSourceFilter string) string {
return fmt.Sprintf(`
resource "octopusdeploy_machine_policy" "policy_1" {
name = "Machine Policy One"
}
resource "octopusdeploy_static_worker_pool" "pool_1" {
name = "Worker Pool One"
description = "First pool of listening workers"
sort_order = 99
}
resource "octopusdeploy_ssh_key_account" "account_1" {
name = "SSH Key Pair Account"
private_key_file = "[private_key_file]"
username = "[username]"
}
resource "octopusdeploy_ssh_connection_worker" "worker_1" {
name = "First SSH worker"
machine_policy_id = octopusdeploy_machine_policy.policy_1.id
worker_pool_ids = [octopusdeploy_static_worker_pool.pool_1.id]
account_id = octopusdeploy_ssh_key_account.account_1.id
host = "test.domain"
port = 4201
fingerprint = "SHA256: 1234abcdef56789"
dotnet_platform = "linux-x64"
}
resource "octopusdeploy_listening_tentacle_worker" "worker_2" {
name = "Second listening worker"
machine_policy_id = octopusdeploy_machine_policy.policy_1.id
worker_pool_ids = [octopusdeploy_static_worker_pool.pool_1.id]
uri = "https://domain.test/"
thumbprint = "abcdef"
}
data "octopusdeploy_workers" "%s" {
%s
}
`,
localName,
dataSourceFilter,
)
}
1 change: 1 addition & 0 deletions octopusdeploy_framework/framework_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func (p *octopusDeployFrameworkProvider) DataSources(ctx context.Context) []func
NewScriptModuleDataSource,
NewTenantProjectDataSource,
NewUsersDataSource,
NewWorkersDataSource,
}
}

Expand Down
Loading

0 comments on commit ee600ff

Please sign in to comment.