From 8cff814252d2313d08eae067abb29c27a407b169 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Fri, 15 Nov 2024 12:58:55 +1300 Subject: [PATCH 1/9] Add workers datasource --- octopusdeploy_framework/datasource_workers.go | 74 +++++++++ octopusdeploy_framework/framework_provider.go | 1 + octopusdeploy_framework/schemas/workers.go | 148 ++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 octopusdeploy_framework/datasource_workers.go create mode 100644 octopusdeploy_framework/schemas/workers.go diff --git a/octopusdeploy_framework/datasource_workers.go b/octopusdeploy_framework/datasource_workers.go new file mode 100644 index 00000000..27a50ee7 --- /dev/null +++ b/octopusdeploy_framework/datasource_workers.go @@ -0,0 +1,74 @@ +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), + WorkerPoolIDs: util.ExpandStringList(data.WorkerPoolIDs), + IsDisabled: data.IsDisabled.ValueBool(), + Thumbprint: data.Thumbprint.ValueString(), + } + + 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)) + + workers := []interface{}{} + for _, worker := range existingWorkers.Items { + workers = append(workers, schemas.FlattenWorker(worker)) + } + + data.Workers, _ = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: schemas.WorkerObjectType()}, workers) + data.ID = types.StringValue("Workers " + time.Now().UTC().String()) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/octopusdeploy_framework/framework_provider.go b/octopusdeploy_framework/framework_provider.go index ab4962f5..b738e4ff 100644 --- a/octopusdeploy_framework/framework_provider.go +++ b/octopusdeploy_framework/framework_provider.go @@ -84,6 +84,7 @@ func (p *octopusDeployFrameworkProvider) DataSources(ctx context.Context) []func NewScriptModuleDataSource, NewTenantProjectDataSource, NewUsersDataSource, + NewWorkersDataSource, } } diff --git a/octopusdeploy_framework/schemas/workers.go b/octopusdeploy_framework/schemas/workers.go new file mode 100644 index 00000000..7e63565c --- /dev/null +++ b/octopusdeploy_framework/schemas/workers.go @@ -0,0 +1,148 @@ +package schemas + +import ( + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/machines" + "github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util" + "github.com/hashicorp/terraform-plugin-framework/attr" + datasourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type WorkersSchema struct{} + +var _ EntitySchema = WorkersSchema{} + +func (f WorkersSchema) GetResourceSchema() resourceSchema.Schema { + return resourceSchema.Schema{} +} + +func (f WorkersSchema) GetDatasourceSchema() datasourceSchema.Schema { + return datasourceSchema.Schema{ + Description: "Provides information about existing workers.", + Attributes: map[string]datasourceSchema.Attribute{ + "ids": GetQueryIDsDatasourceSchema(), + "name": GetNameDatasourceSchema(false), + "partial_name": GetQueryPartialNameDatasourceSchema(), + "skip": GetQuerySkipDatasourceSchema(), + "take": GetQueryTakeDatasourceSchema(), + "space_id": GetSpaceIdDatasourceSchema("workers", false), + "communication_styles": datasourceSchema.ListAttribute{ + Description: "A filter to search by communication styles", + ElementType: types.StringType, + Optional: true, + }, + "health_statuses": datasourceSchema.ListAttribute{ + Description: "A filter to search by health statuses", + ElementType: types.StringType, + Optional: true, + }, + "worker_pool_ids": datasourceSchema.ListAttribute{ + Description: "A filter to search by worker pools", + ElementType: types.StringType, + Optional: true, + }, + "is_disabled": GetBooleanDatasourceAttribute("", true), + "thumbprint": datasourceSchema.StringAttribute{ + Description: "A filter search by worker's thumbprint", + Optional: true, + }, + + // response + "id": GetIdDatasourceSchema(true), + "workers": datasourceSchema.ListNestedAttribute{ + Computed: true, + Optional: false, + NestedObject: datasourceSchema.NestedAttributeObject{ + Attributes: map[string]datasourceSchema.Attribute{ + "id": GetIdDatasourceSchema(true), + "space_id": GetSpaceIdDatasourceSchema("feeds", true), + "name": GetReadonlyNameDatasourceSchema(), + "is_disabled": datasourceSchema.BoolAttribute{ + Computed: true, + }, + "machine_policy_id": datasourceSchema.StringAttribute{ + Computed: true, + }, + "worker_pool_ids": datasourceSchema.SetAttribute{ + ElementType: types.StringType, + Computed: true, + }, + "proxy_id": datasourceSchema.StringAttribute{ + Computed: true, + }, + "uri": datasourceSchema.StringAttribute{ + Computed: true, + }, + "thumbprint": datasourceSchema.StringAttribute{ + Computed: true, + }, + "account_id": datasourceSchema.StringAttribute{ + Computed: true, + }, + "host": datasourceSchema.StringAttribute{ + Computed: true, + }, + "port": datasourceSchema.Int64Attribute{ + Computed: true, + }, + "fingerprint": datasourceSchema.StringAttribute{ + Computed: true, + }, + "dotnet_platform": datasourceSchema.StringAttribute{ + Computed: true, + }, + }, + }, + }, + }, + } +} + +type WorkersDataSourceModel struct { + ID types.String `tfsdk:"id"` + IDs types.List `tfsdk:"ids"` + Name types.String `tfsdk:"name"` + PartialName types.String `tfsdk:"partial_name"` + Skip types.Int64 `tfsdk:"skip"` + Take types.Int64 `tfsdk:"take"` + SpaceID types.String `tfsdk:"space_id"` + CommunicationStyle types.List `tfsdk:"health_statuses"` + HealthStatuses types.List `tfsdk:"communication_styles"` + WorkerPoolIDs types.List `tfsdk:"worker_pool_ids"` + IsDisabled types.Bool `tfsdk:"is_disabled"` + Thumbprint types.String `tfsdk:"thumbprint"` + Workers types.List `tfsdk:"workers"` +} + +func FlattenWorker(worker *machines.Worker) attr.Value { + return types.ObjectValueMust(WorkerObjectType(), map[string]attr.Value{ + "id": types.StringValue(worker.GetID()), + "name": types.StringValue(worker.Name), + "is_disabled": types.BoolValue(worker.IsDisabled), + "communication_style": types.StringValue(worker.Endpoint.GetCommunicationStyle()), + "health_status": types.StringValue(worker.HealthStatus), + "machine_policy_id": types.StringValue(worker.MachinePolicyID), + "worker_pool_ids": types.ListValueMust(types.StringType, util.ToValueSlice(worker.WorkerPoolIDs)), + }) +} + +func WorkerObjectType() map[string]attr.Type { + return map[string]attr.Type{ + "id": types.StringType, + "name": types.StringType, + "is_disabled": types.BoolType, + "communication_style": types.StringType, + "health_status": types.StringType, + "machine_policy_id": types.StringType, + "worker_pool_ids": types.ListType{ElemType: types.StringType}, + //"proxy_id": types.StringType, // Endpoint specific values + //"uri": types.StringType, + //"thumbprint": types.StringType, + //"account_id": types.StringType, + //"host": types.StringType, + //"port": types.Int64Type, + //"fingerprint": types.StringType, + //"dotnet_platform": types.StringType, + } +} From 4bcbee28ad3aa2c5ac23b6bef19fa69571816c28 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 11:02:46 +1300 Subject: [PATCH 2/9] Add test and docs for workers datasource --- docs/data-sources/workers.md | 70 +++++++++ .../octopusdeploy_workers/data-source.tf | 10 ++ octopusdeploy_framework/datasource_workers.go | 8 +- .../datasource_workers_test.go | 136 ++++++++++++++++++ octopusdeploy_framework/schemas/workers.go | 74 +++++++--- 5 files changed, 270 insertions(+), 28 deletions(-) create mode 100644 docs/data-sources/workers.md create mode 100644 examples/data-sources/octopusdeploy_workers/data-source.tf create mode 100644 octopusdeploy_framework/datasource_workers_test.go diff --git a/docs/data-sources/workers.md b/docs/data-sources/workers.md new file mode 100644 index 00000000..059e2128 --- /dev/null +++ b/docs/data-sources/workers.md @@ -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 + +### 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)) + + +### 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) + + diff --git a/examples/data-sources/octopusdeploy_workers/data-source.tf b/examples/data-sources/octopusdeploy_workers/data-source.tf new file mode 100644 index 00000000..9b8ecedf --- /dev/null +++ b/examples/data-sources/octopusdeploy_workers/data-source.tf @@ -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 +} \ No newline at end of file diff --git a/octopusdeploy_framework/datasource_workers.go b/octopusdeploy_framework/datasource_workers.go index 27a50ee7..fcdf9ecf 100644 --- a/octopusdeploy_framework/datasource_workers.go +++ b/octopusdeploy_framework/datasource_workers.go @@ -47,9 +47,7 @@ func (e *workersDataSource) Read(ctx context.Context, req datasource.ReadRequest Take: util.GetNumber(data.Take), CommunicationStyles: util.ExpandStringList(data.CommunicationStyle), HealthStatuses: util.ExpandStringList(data.HealthStatuses), - WorkerPoolIDs: util.ExpandStringList(data.WorkerPoolIDs), IsDisabled: data.IsDisabled.ValueBool(), - Thumbprint: data.Thumbprint.ValueString(), } util.DatasourceReading(ctx, "workers", query) @@ -62,12 +60,12 @@ func (e *workersDataSource) Read(ctx context.Context, req datasource.ReadRequest util.DatasourceResultCount(ctx, "workers", len(existingWorkers.Items)) - workers := []interface{}{} + resources := []interface{}{} for _, worker := range existingWorkers.Items { - workers = append(workers, schemas.FlattenWorker(worker)) + resources = append(resources, schemas.FlattenWorker(worker)) } - data.Workers, _ = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: schemas.WorkerObjectType()}, workers) + 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)...) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go new file mode 100644 index 00000000..9e0aa381 --- /dev/null +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -0,0 +1,136 @@ +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) + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: ProtoV6ProviderFactories(), + PreCheck: func() { TestAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: createTestAccDataSourceWorkerResources(), + }, + { + Config: createTestAccDataSourceWorkersEmpty(localName), + Check: testAssertDataSourceWorkersEmpty(prefix), + }, + { + Config: createTestAccDataSourceSSHWorkers(localName), + Check: testAssertDataSourceSSHWorkers(prefix), + }, + { + Config: createTestAccDataSourceListeningWorkers(localName), + Check: testAssertDataSourceListeningWorkers(prefix), + }, + }, + }) +} + +func createTestAccDataSourceWorkersEmpty(localName string) string { + return fmt.Sprintf(`data "octopusdeploy_workers" "%s" {}`, localName) +} + +func testAssertDataSourceWorkersEmpty(prefix string) resource.TestCheckFunc { + return resource.ComposeTestCheckFunc( + testAssertWorkersDataSourceID(prefix), + resource.TestCheckResourceAttr(prefix, "workers.#", "2"), + ) +} + +func createTestAccDataSourceSSHWorkers(localName string) string { + return fmt.Sprintf(`data "octopusdeploy_workers" "%s" { + communication_styles = ["Ssh"] + }`, localName) +} + +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 createTestAccDataSourceListeningWorkers(localName string) string { + return fmt.Sprintf(`data "octopusdeploy_workers" "%s" { + communication_styles = ["TentaclePassive"] + }`, localName) +} + +func testAssertDataSourceListeningWorkers(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].uri", "https://domain.test"), + resource.TestCheckResourceAttr(prefix, "workers[0].thumbprint", "absdef"), + ) +} + +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 createTestAccDataSourceWorkerResources() string { + return `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" + } +` +} diff --git a/octopusdeploy_framework/schemas/workers.go b/octopusdeploy_framework/schemas/workers.go index 7e63565c..e9602d6d 100644 --- a/octopusdeploy_framework/schemas/workers.go +++ b/octopusdeploy_framework/schemas/workers.go @@ -37,16 +37,7 @@ func (f WorkersSchema) GetDatasourceSchema() datasourceSchema.Schema { ElementType: types.StringType, Optional: true, }, - "worker_pool_ids": datasourceSchema.ListAttribute{ - Description: "A filter to search by worker pools", - ElementType: types.StringType, - Optional: true, - }, "is_disabled": GetBooleanDatasourceAttribute("", true), - "thumbprint": datasourceSchema.StringAttribute{ - Description: "A filter search by worker's thumbprint", - Optional: true, - }, // response "id": GetIdDatasourceSchema(true), @@ -56,7 +47,7 @@ func (f WorkersSchema) GetDatasourceSchema() datasourceSchema.Schema { NestedObject: datasourceSchema.NestedAttributeObject{ Attributes: map[string]datasourceSchema.Attribute{ "id": GetIdDatasourceSchema(true), - "space_id": GetSpaceIdDatasourceSchema("feeds", true), + "space_id": GetSpaceIdDatasourceSchema("workers", true), "name": GetReadonlyNameDatasourceSchema(), "is_disabled": datasourceSchema.BoolAttribute{ Computed: true, @@ -64,10 +55,16 @@ func (f WorkersSchema) GetDatasourceSchema() datasourceSchema.Schema { "machine_policy_id": datasourceSchema.StringAttribute{ Computed: true, }, - "worker_pool_ids": datasourceSchema.SetAttribute{ + "worker_pool_ids": datasourceSchema.ListAttribute{ ElementType: types.StringType, Computed: true, }, + "communication_style": datasourceSchema.StringAttribute{ + Computed: true, + }, + "health_status": datasourceSchema.StringAttribute{ + Computed: true, + }, "proxy_id": datasourceSchema.StringAttribute{ Computed: true, }, @@ -107,42 +104,73 @@ type WorkersDataSourceModel struct { Skip types.Int64 `tfsdk:"skip"` Take types.Int64 `tfsdk:"take"` SpaceID types.String `tfsdk:"space_id"` - CommunicationStyle types.List `tfsdk:"health_statuses"` - HealthStatuses types.List `tfsdk:"communication_styles"` - WorkerPoolIDs types.List `tfsdk:"worker_pool_ids"` + CommunicationStyle types.List `tfsdk:"communication_styles"` + HealthStatuses types.List `tfsdk:"health_statuses"` IsDisabled types.Bool `tfsdk:"is_disabled"` - Thumbprint types.String `tfsdk:"thumbprint"` Workers types.List `tfsdk:"workers"` } func FlattenWorker(worker *machines.Worker) attr.Value { + proxyId := types.StringNull() + uri := types.StringNull() + thumbprint := types.StringNull() + accountId := types.StringNull() + host := types.StringNull() + port := types.Int64Null() + fingerprint := types.StringNull() + dotnetPlatform := types.StringNull() + + switch endpoint := worker.Endpoint.(type) { + case *machines.ListeningTentacleEndpoint: + proxyId = util.StringOrNull(endpoint.ProxyID) + uri = util.StringOrNull(endpoint.URI.String()) + thumbprint = util.StringOrNull(endpoint.Thumbprint) + case *machines.SSHEndpoint: + proxyId = util.StringOrNull(endpoint.ProxyID) + accountId = util.StringOrNull(endpoint.AccountID) + host = util.StringOrNull(endpoint.Host) + port = types.Int64Value(int64(endpoint.Port)) + fingerprint = util.StringOrNull(endpoint.Fingerprint) + dotnetPlatform = util.StringOrNull(endpoint.DotNetCorePlatform) + } + return types.ObjectValueMust(WorkerObjectType(), map[string]attr.Value{ "id": types.StringValue(worker.GetID()), + "space_id": types.StringValue(worker.SpaceID), "name": types.StringValue(worker.Name), "is_disabled": types.BoolValue(worker.IsDisabled), "communication_style": types.StringValue(worker.Endpoint.GetCommunicationStyle()), "health_status": types.StringValue(worker.HealthStatus), "machine_policy_id": types.StringValue(worker.MachinePolicyID), "worker_pool_ids": types.ListValueMust(types.StringType, util.ToValueSlice(worker.WorkerPoolIDs)), + "proxy_id": proxyId, + "uri": uri, + "thumbprint": thumbprint, + "account_id": accountId, + "host": host, + "port": port, + "fingerprint": fingerprint, + "dotnet_platform": dotnetPlatform, }) } func WorkerObjectType() map[string]attr.Type { return map[string]attr.Type{ "id": types.StringType, + "space_id": types.StringType, "name": types.StringType, "is_disabled": types.BoolType, "communication_style": types.StringType, "health_status": types.StringType, "machine_policy_id": types.StringType, "worker_pool_ids": types.ListType{ElemType: types.StringType}, - //"proxy_id": types.StringType, // Endpoint specific values - //"uri": types.StringType, - //"thumbprint": types.StringType, - //"account_id": types.StringType, - //"host": types.StringType, - //"port": types.Int64Type, - //"fingerprint": types.StringType, - //"dotnet_platform": types.StringType, + "proxy_id": types.StringType, + "uri": types.StringType, + "thumbprint": types.StringType, + "account_id": types.StringType, + "host": types.StringType, + "port": types.Int64Type, + "fingerprint": types.StringType, + "dotnet_platform": types.StringType, } } From 23c493a7b4f14c93a132b657fd0b7ce5febe212e Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 11:18:14 +1300 Subject: [PATCH 3/9] Fix incorrect value which produced inconsistent result in terraform state --- octopusdeploy_framework/datasource_workers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 9e0aa381..10619663 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -77,7 +77,7 @@ func testAssertDataSourceListeningWorkers(prefix string) resource.TestCheckFunc testAssertWorkersDataSourceID(prefix), resource.TestCheckResourceAttr(prefix, "workers.#", "1"), resource.TestCheckResourceAttr(prefix, "workers[0].name", "First SSH worker"), - resource.TestCheckResourceAttr(prefix, "workers[0].uri", "https://domain.test"), + resource.TestCheckResourceAttr(prefix, "workers[0].uri", "https://domain.test/"), resource.TestCheckResourceAttr(prefix, "workers[0].thumbprint", "absdef"), ) } From a87bf212991343b33e69d65b292793058845b503 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 11:37:18 +1300 Subject: [PATCH 4/9] Fix incorrect value which produced inconsistent result in terraform state --- octopusdeploy_framework/datasource_workers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 10619663..260910b4 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -129,7 +129,7 @@ func createTestAccDataSourceWorkerResources() string { 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" + uri = "https://domain.test/" thumbprint = "abcdef" } ` From 3eaa30b07df57b77dcab7ac263e27485b0a1328e Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 12:49:09 +1300 Subject: [PATCH 5/9] Keep resource in configuration for all steps so terraform will not destroy them. --- .../datasource_workers_test.go | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 260910b4..07c7fcb6 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -13,34 +13,29 @@ import ( 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: createTestAccDataSourceWorkerResources(), - }, - { - Config: createTestAccDataSourceWorkersEmpty(localName), + Config: createTestAccDataSourceWorkerResources(localName, ""), Check: testAssertDataSourceWorkersEmpty(prefix), }, { - Config: createTestAccDataSourceSSHWorkers(localName), + Config: createTestAccDataSourceWorkerResources(localName, sshFilter), Check: testAssertDataSourceSSHWorkers(prefix), }, { - Config: createTestAccDataSourceListeningWorkers(localName), + Config: createTestAccDataSourceWorkerResources(localName, listeningFilter), Check: testAssertDataSourceListeningWorkers(prefix), }, }, }) } -func createTestAccDataSourceWorkersEmpty(localName string) string { - return fmt.Sprintf(`data "octopusdeploy_workers" "%s" {}`, localName) -} - func testAssertDataSourceWorkersEmpty(prefix string) resource.TestCheckFunc { return resource.ComposeTestCheckFunc( testAssertWorkersDataSourceID(prefix), @@ -48,12 +43,6 @@ func testAssertDataSourceWorkersEmpty(prefix string) resource.TestCheckFunc { ) } -func createTestAccDataSourceSSHWorkers(localName string) string { - return fmt.Sprintf(`data "octopusdeploy_workers" "%s" { - communication_styles = ["Ssh"] - }`, localName) -} - func testAssertDataSourceSSHWorkers(prefix string) resource.TestCheckFunc { return resource.ComposeTestCheckFunc( testAssertWorkersDataSourceID(prefix), @@ -66,12 +55,6 @@ func testAssertDataSourceSSHWorkers(prefix string) resource.TestCheckFunc { ) } -func createTestAccDataSourceListeningWorkers(localName string) string { - return fmt.Sprintf(`data "octopusdeploy_workers" "%s" { - communication_styles = ["TentaclePassive"] - }`, localName) -} - func testAssertDataSourceListeningWorkers(prefix string) resource.TestCheckFunc { return resource.ComposeTestCheckFunc( testAssertWorkersDataSourceID(prefix), @@ -97,8 +80,9 @@ func testAssertWorkersDataSourceID(prefix string) resource.TestCheckFunc { } } -func createTestAccDataSourceWorkerResources() string { - return `resource "octopusdeploy_machine_policy" "policy_1" { +func createTestAccDataSourceWorkerResources(localName string, dataSourceFilter string) string { + return fmt.Sprintf(` + resource "octopusdeploy_machine_policy" "policy_1" { name = "Machine Policy One" } @@ -132,5 +116,12 @@ func createTestAccDataSourceWorkerResources() string { uri = "https://domain.test/" thumbprint = "abcdef" } -` + + data "octopusdeploy_workers" "%s" { + %s + } + `, + localName, + dataSourceFilter, + ) } From 8602ef47684d07baab1b90426e2fd6457d24fd6a Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 13:34:47 +1300 Subject: [PATCH 6/9] Add resources in a step before step with assertion --- octopusdeploy_framework/datasource_workers_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 07c7fcb6..120b10ea 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -21,15 +21,18 @@ func TestAccDataSourceWorkers(t *testing.T) { PreCheck: func() { TestAccPreCheck(t) }, Steps: []resource.TestStep{ { - Config: createTestAccDataSourceWorkerResources(localName, ""), + Config: configTestAccDataSourceWorkerResources(localName, ""), + }, + { + Config: configTestAccDataSourceWorkerResources(localName, ""), Check: testAssertDataSourceWorkersEmpty(prefix), }, { - Config: createTestAccDataSourceWorkerResources(localName, sshFilter), + Config: configTestAccDataSourceWorkerResources(localName, sshFilter), Check: testAssertDataSourceSSHWorkers(prefix), }, { - Config: createTestAccDataSourceWorkerResources(localName, listeningFilter), + Config: configTestAccDataSourceWorkerResources(localName, listeningFilter), Check: testAssertDataSourceListeningWorkers(prefix), }, }, @@ -80,7 +83,7 @@ func testAssertWorkersDataSourceID(prefix string) resource.TestCheckFunc { } } -func createTestAccDataSourceWorkerResources(localName string, dataSourceFilter string) string { +func configTestAccDataSourceWorkerResources(localName string, dataSourceFilter string) string { return fmt.Sprintf(` resource "octopusdeploy_machine_policy" "policy_1" { name = "Machine Policy One" From e8cf610f042a409f0ce126b2f5826c1b4ab156df Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 14:42:15 +1300 Subject: [PATCH 7/9] Use dot notation to access element of the list by their index --- .../datasource_workers_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 120b10ea..14585d4e 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -50,11 +50,11 @@ 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"), + 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"), ) } @@ -62,9 +62,9 @@ func testAssertDataSourceListeningWorkers(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].uri", "https://domain.test/"), - resource.TestCheckResourceAttr(prefix, "workers[0].thumbprint", "absdef"), + resource.TestCheckResourceAttr(prefix, "workers.0.name", "First SSH worker"), + resource.TestCheckResourceAttr(prefix, "workers.0.uri", "https://domain.test/"), + resource.TestCheckResourceAttr(prefix, "workers.0.thumbprint", "absdef"), ) } From a468fc59e8022e6308155409d472848abb5a60f6 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 15:03:06 +1300 Subject: [PATCH 8/9] Use correct expected value for worker name --- octopusdeploy_framework/datasource_workers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 14585d4e..47a0ed54 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -62,7 +62,7 @@ func testAssertDataSourceListeningWorkers(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.name", "Second listening worker"), resource.TestCheckResourceAttr(prefix, "workers.0.uri", "https://domain.test/"), resource.TestCheckResourceAttr(prefix, "workers.0.thumbprint", "absdef"), ) From 76686c26f30f1096d64474c32b7a5416dd31e463 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Tue, 19 Nov 2024 16:00:47 +1300 Subject: [PATCH 9/9] Use correct expected value for worker --- octopusdeploy_framework/datasource_workers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octopusdeploy_framework/datasource_workers_test.go b/octopusdeploy_framework/datasource_workers_test.go index 47a0ed54..100297be 100644 --- a/octopusdeploy_framework/datasource_workers_test.go +++ b/octopusdeploy_framework/datasource_workers_test.go @@ -64,7 +64,7 @@ func testAssertDataSourceListeningWorkers(prefix string) resource.TestCheckFunc 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", "absdef"), + resource.TestCheckResourceAttr(prefix, "workers.0.thumbprint", "abcdef"), ) }