summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuzhang3 <57888764+xuzhang3@users.noreply.github.com>2023-02-21 11:07:59 +0800
committerGitHub <noreply@github.com>2023-02-21 11:07:59 +0800
commit038a57763e38b94214d08deb1a508f99adc73cc9 (patch)
tree9f8d11ee1004b1a0f1dc3010d4294faee2318855
parent7d1d91cebb7b6ab89faaacf07eae799496b4822e (diff)
parent444277addccc91aa0de5eeb92e9e354933eaf9ab (diff)
Merge pull request #716 from xuzhang3/f/agent_pool_optimize
`azuredevops_agent_pool` - Add status handler
-rw-r--r--azuredevops/internal/acceptancetests/data_agentpool_test.go24
-rw-r--r--azuredevops/internal/acceptancetests/resource_agentpool_test.go147
-rw-r--r--azuredevops/internal/service/taskagent/data_agentpool.go67
-rw-r--r--azuredevops/internal/service/taskagent/resource_agent_queue.go4
-rw-r--r--azuredevops/internal/service/taskagent/resource_agentpool.go200
-rw-r--r--azuredevops/internal/service/taskagent/resource_agentpool_test.go172
-rw-r--r--azuredevops/internal/utils/converter/converter.go4
7 files changed, 288 insertions, 330 deletions
diff --git a/azuredevops/internal/acceptancetests/data_agentpool_test.go b/azuredevops/internal/acceptancetests/data_agentpool_test.go
index 4e190007..fe8d837f 100644
--- a/azuredevops/internal/acceptancetests/data_agentpool_test.go
+++ b/azuredevops/internal/acceptancetests/data_agentpool_test.go
@@ -12,18 +12,16 @@ import (
"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/acceptancetests/testutils"
)
-func TestAccAgentPool_DataSource(t *testing.T) {
+func TestAccDataSourceAgentPool_basic(t *testing.T) {
agentPoolName := testutils.GenerateResourceName()
- createAgentPool := testutils.HclAgentPoolResource(agentPoolName)
- createAndGetAgentPoolData := fmt.Sprintf("%s\n%s", createAgentPool, testutils.HclAgentPoolDataSource())
+ tfNode := "data.azuredevops_agent_pool.test"
- tfNode := "data.azuredevops_agent_pool.pool"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testutils.PreCheck(t, nil) },
Providers: testutils.GetProviders(),
Steps: []resource.TestStep{
{
- Config: createAndGetAgentPoolData,
+ Config: hclDataSourceAgentPoolBasic(agentPoolName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(tfNode, "id"),
resource.TestCheckResourceAttr(tfNode, "name", agentPoolName),
@@ -35,3 +33,19 @@ func TestAccAgentPool_DataSource(t *testing.T) {
},
})
}
+
+func hclDataSourceAgentPoolBasic(name string) string {
+ return fmt.Sprintf(`
+resource "azuredevops_agent_pool" "test" {
+ name = "%s"
+ auto_provision = false
+ auto_update = false
+ pool_type = "automation"
+}
+
+data "azuredevops_agent_pool" "test" {
+ name = azuredevops_agent_pool.test.name
+}
+
+`, name)
+}
diff --git a/azuredevops/internal/acceptancetests/resource_agentpool_test.go b/azuredevops/internal/acceptancetests/resource_agentpool_test.go
index 6b1058d1..5f6c5c81 100644
--- a/azuredevops/internal/acceptancetests/resource_agentpool_test.go
+++ b/azuredevops/internal/acceptancetests/resource_agentpool_test.go
@@ -6,6 +6,7 @@ package acceptancetests
import (
"fmt"
+ "regexp"
"strconv"
"testing"
@@ -16,19 +17,9 @@ import (
"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client"
)
-// Verifies that the following sequence of events occurrs without error:
-//
-// (1) TF apply creates agent pool
-// (2) TF state values are set
-// (3) Agent pool can be queried by ID and has expected name
-// (4) TF apply updates agent pool with new name
-// (5) Agent pool can be queried by ID and has expected name
-// (6) TF destroy deletes agent pool
-// (7) Agent pool can no longer be queried by ID
-func TestAccAgentPool_CreateAndUpdate(t *testing.T) {
- poolNameFirst := testutils.GenerateResourceName()
- poolNameSecond := testutils.GenerateResourceName()
- tfNode := "azuredevops_agent_pool.pool"
+func TestAccAgentPool_basic(t *testing.T) {
+ poolName := testutils.GenerateResourceName()
+ tfNode := "azuredevops_agent_pool.test"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testutils.PreCheck(t, nil) },
@@ -36,27 +27,56 @@ func TestAccAgentPool_CreateAndUpdate(t *testing.T) {
CheckDestroy: checkAgentPoolDestroyed,
Steps: []resource.TestStep{
{
- Config: testutils.HclAgentPoolResource(poolNameFirst),
+ Config: hclAgentPoolBasic(poolName),
Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr(tfNode, "name", poolNameFirst),
+ resource.TestCheckResourceAttr(tfNode, "name", poolName),
resource.TestCheckResourceAttr(tfNode, "auto_provision", "false"),
resource.TestCheckResourceAttr(tfNode, "auto_update", "false"),
resource.TestCheckResourceAttr(tfNode, "pool_type", "automation"),
- checkAgentPoolExists(poolNameFirst),
),
},
{
- Config: testutils.HclAgentPoolResource(poolNameSecond),
+ ResourceName: tfNode,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ },
+ })
+}
+
+func TestAccAgentPool_update(t *testing.T) {
+ poolName := testutils.GenerateResourceName()
+ tfNode := "azuredevops_agent_pool.test"
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testutils.PreCheck(t, nil) },
+ Providers: testutils.GetProviders(),
+ CheckDestroy: checkAgentPoolDestroyed,
+ Steps: []resource.TestStep{
+ {
+ Config: hclAgentPoolBasic(poolName),
Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr(tfNode, "name", poolNameSecond),
+ resource.TestCheckResourceAttr(tfNode, "name", poolName),
resource.TestCheckResourceAttr(tfNode, "auto_provision", "false"),
resource.TestCheckResourceAttr(tfNode, "auto_update", "false"),
resource.TestCheckResourceAttr(tfNode, "pool_type", "automation"),
- checkAgentPoolExists(poolNameSecond),
),
},
{
- // Resource Acceptance Testing https://www.terraform.io/docs/extend/resources/import.html#resource-acceptance-testing-implementation
+ ResourceName: tfNode,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ {
+ Config: hclAgentPoolUpdate(poolName),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(tfNode, "name", poolName),
+ resource.TestCheckResourceAttr(tfNode, "auto_provision", "true"),
+ resource.TestCheckResourceAttr(tfNode, "auto_update", "true"),
+ resource.TestCheckResourceAttr(tfNode, "pool_type", "automation"),
+ ),
+ },
+ {
ResourceName: tfNode,
ImportState: true,
ImportStateVerify: true,
@@ -65,37 +85,33 @@ func TestAccAgentPool_CreateAndUpdate(t *testing.T) {
})
}
-// Given the name of an agent pool, this will return a function that will check whether
-// or not the pool (1) exists in the state and (2) exist in AzDO and (3) has the correct name
-func checkAgentPoolExists(expectedName string) resource.TestCheckFunc {
- return func(s *terraform.State) error {
- resource, ok := s.RootModule().Resources["azuredevops_agent_pool.pool"]
- if !ok {
- return fmt.Errorf("Did not find a agent pool in the TF state")
- }
-
- clients := testutils.GetProvider().Meta().(*client.AggregatedClient)
- id, err := strconv.Atoi(resource.Primary.ID)
- if err != nil {
- return fmt.Errorf("Parse ID error, ID: %v !. Error= %v", resource.Primary.ID, err)
- }
-
- pool, agentPoolErr := clients.TaskAgentClient.GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{PoolId: &id})
-
- if agentPoolErr != nil {
- return fmt.Errorf("Agent Pool with ID=%d cannot be found!. Error=%v", id, err)
- }
+func TestAccAgentPool_requiresImportErrorStep(t *testing.T) {
+ poolName := testutils.GenerateResourceName()
+ tfNode := "azuredevops_agent_pool.test"
- if *pool.Name != expectedName {
- return fmt.Errorf("Agent Pool with ID=%d has Name=%s, but expected Name=%s", id, *pool.Name, expectedName)
- }
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testutils.PreCheck(t, nil) },
+ Providers: testutils.GetProviders(),
+ CheckDestroy: checkAgentPoolDestroyed,
+ Steps: []resource.TestStep{
+ {
+ Config: hclAgentPoolBasic(poolName),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(tfNode, "name", poolName),
+ resource.TestCheckResourceAttr(tfNode, "auto_provision", "false"),
+ resource.TestCheckResourceAttr(tfNode, "auto_update", "false"),
+ resource.TestCheckResourceAttr(tfNode, "pool_type", "automation"),
+ ),
+ },
- return nil
- }
+ {
+ Config: hclAgentPoolResourceRequiresImport(poolName),
+ ExpectError: requiresImportError(poolName),
+ },
+ },
+ })
}
-// verifies that agent pool referenced in the state is destroyed. This will be invoked
-// *after* terraform destroys the resource but *before* the state is wiped clean.
func checkAgentPoolDestroyed(s *terraform.State) error {
clients := testutils.GetProvider().Meta().(*client.AggregatedClient)
@@ -118,3 +134,40 @@ func checkAgentPoolDestroyed(s *terraform.State) error {
return nil
}
+
+func requiresImportError(resourceName string) *regexp.Regexp {
+ message := "creating agent pool in Azure DevOps: Agent pool %[1]s already exists."
+ return regexp.MustCompile(fmt.Sprintf(message, resourceName))
+}
+
+func hclAgentPoolBasic(name string) string {
+ return fmt.Sprintf(`
+resource "azuredevops_agent_pool" "test" {
+ name = "%s"
+ auto_provision = false
+ auto_update = false
+ pool_type = "automation"
+}`, name)
+}
+
+func hclAgentPoolUpdate(name string) string {
+ return fmt.Sprintf(`
+resource "azuredevops_agent_pool" "test" {
+ name = "%s"
+ auto_provision = true
+ auto_update = true
+ pool_type = "automation"
+}`, name)
+}
+
+func hclAgentPoolResourceRequiresImport(name string) string {
+ return fmt.Sprintf(`
+%s
+
+resource "azuredevops_agent_pool" "import" {
+ name = azuredevops_agent_pool.test.name
+ auto_provision = azuredevops_agent_pool.test.auto_provision
+ auto_update = azuredevops_agent_pool.test.auto_update
+ pool_type = azuredevops_agent_pool.test.pool_type
+}`, hclAgentPoolBasic(name))
+}
diff --git a/azuredevops/internal/service/taskagent/data_agentpool.go b/azuredevops/internal/service/taskagent/data_agentpool.go
index 914f6bd2..6a9800da 100644
--- a/azuredevops/internal/service/taskagent/data_agentpool.go
+++ b/azuredevops/internal/service/taskagent/data_agentpool.go
@@ -2,59 +2,72 @@ package taskagent
import (
"fmt"
+ "strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/microsoft/azure-devops-go-api/azuredevops/v6/taskagent"
"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client"
+ "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter"
)
// DataAgentPool schema and implementation for agent pool data source
func DataAgentPool() *schema.Resource {
- baseSchema := ResourceAgentPool()
- for k, v := range baseSchema.Schema {
- if k != "name" {
- baseSchema.Schema[k] = &schema.Schema{
- Type: v.Type,
- Computed: true,
- }
- }
- }
-
return &schema.Resource{
- Read: dataSourceAgentPoolRead,
- Schema: baseSchema.Schema,
+ Read: dataSourceAgentPoolRead,
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ ForceNew: false,
+ Required: true,
+ ValidateFunc: validation.StringIsNotWhiteSpace,
+ },
+ "pool_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "auto_provision": {
+ Type: schema.TypeBool,
+ Computed: true,
+ },
+ "auto_update": {
+ Type: schema.TypeBool,
+ Computed: true,
+ },
+ },
}
}
func dataSourceAgentPoolRead(d *schema.ResourceData, m interface{}) error {
- agentPoolName := d.Get("name").(string)
clients := m.(*client.AggregatedClient)
- agentPool, err := getAgentPoolByName(clients, &agentPoolName)
- if err != nil {
- return fmt.Errorf("Error getting agent pool by name: %v", err)
- }
+ poolName := d.Get("name").(string)
- flattenAzureAgentPool(d, agentPool)
- return nil
-}
-
-func getAgentPoolByName(clients *client.AggregatedClient, name *string) (*taskagent.TaskAgentPool, error) {
agentPools, err := clients.TaskAgentClient.GetAgentPools(clients.Ctx, taskagent.GetAgentPoolsArgs{
- PoolName: name,
+ PoolName: converter.String(poolName),
})
if err != nil {
- return nil, err
+ return err
}
if len(*agentPools) > 1 {
- return nil, fmt.Errorf("Found multiple agent pools for name: %s. Agent pools found: %+v", *name, agentPools)
+ return fmt.Errorf(" Found multiple agent pools for name: %s. Agent pools found: %+v", poolName, agentPools)
}
if len(*agentPools) == 0 {
- return nil, fmt.Errorf("Unable to find agent pool with name: %s", *name)
+ return fmt.Errorf(" Unable to find agent pool with name: %s", poolName)
}
- return &(*agentPools)[0], nil
+ pool := (*agentPools)[0]
+
+ d.SetId(strconv.Itoa(*pool.Id))
+ d.Set("name", pool.Name)
+ d.Set("pool_type", *pool.PoolType)
+ d.Set("auto_provision", *pool.AutoProvision)
+
+ if pool.AutoUpdate != nil {
+ d.Set("auto_update", *pool.AutoUpdate)
+ }
+ return nil
}
diff --git a/azuredevops/internal/service/taskagent/resource_agent_queue.go b/azuredevops/internal/service/taskagent/resource_agent_queue.go
index 04c18284..5a810163 100644
--- a/azuredevops/internal/service/taskagent/resource_agent_queue.go
+++ b/azuredevops/internal/service/taskagent/resource_agent_queue.go
@@ -52,7 +52,9 @@ func resourceAgentQueueCreate(d *schema.ResourceData, m interface{}) error {
return fmt.Errorf("Error expanding the agent queue resource from state: %+v", err)
}
- referencedPool, err := azureAgentPoolRead(clients, *queue.Pool.Id)
+ referencedPool, err := clients.TaskAgentClient.GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{
+ PoolId: queue.Pool.Id,
+ })
if err != nil {
return fmt.Errorf("Error looking up referenced agent pool: %+v", err)
}
diff --git a/azuredevops/internal/service/taskagent/resource_agentpool.go b/azuredevops/internal/service/taskagent/resource_agentpool.go
index 0cb02a8d..51ef9c8b 100644
--- a/azuredevops/internal/service/taskagent/resource_agentpool.go
+++ b/azuredevops/internal/service/taskagent/resource_agentpool.go
@@ -3,7 +3,9 @@ package taskagent
import (
"fmt"
"strconv"
+ "time"
+ "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/helper/validation"
"github.com/microsoft/azure-devops-go-api/azuredevops/v6/taskagent"
@@ -23,6 +25,12 @@ func ResourceAgentPool() *schema.Resource {
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
+ Timeouts: &schema.ResourceTimeout{
+ Create: schema.DefaultTimeout(10 * time.Minute),
+ Read: schema.DefaultTimeout(5 * time.Minute),
+ Update: schema.DefaultTimeout(10 * time.Minute),
+ Delete: schema.DefaultTimeout(10 * time.Minute),
+ },
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
@@ -57,59 +65,97 @@ func ResourceAgentPool() *schema.Resource {
func resourceAzureAgentPoolCreate(d *schema.ResourceData, m interface{}) error {
clients := m.(*client.AggregatedClient)
- agentPool, err := expandAgentPool(d, true)
- if err != nil {
- return fmt.Errorf("Error converting terraform data model to AzDO agentPool reference: %+v", err)
+
+ args := taskagent.AddAgentPoolArgs{
+ Pool: &taskagent.TaskAgentPool{
+ Name: converter.String(d.Get("name").(string)),
+ PoolType: converter.ToPtr(taskagent.TaskAgentPoolType(d.Get("pool_type").(string))),
+ AutoProvision: converter.Bool(d.Get("auto_provision").(bool)),
+ AutoUpdate: converter.Bool(d.Get("auto_update").(bool)),
+ },
}
- createdAgentPool, err := createAzureAgentPool(clients, agentPool)
+ agentPool, err := clients.TaskAgentClient.AddAgentPool(clients.Ctx, args)
if err != nil {
- return fmt.Errorf("Error creating agent pool in Azure DevOps: %+v", err)
+ return fmt.Errorf(" creating agent pool in Azure DevOps: %+v", err)
}
- if agentPool.AutoUpdate != nil && !*agentPool.AutoUpdate {
- agentPool.Id = createdAgentPool.Id
- createdAgentPool, err = azureAgentPoolUpdate(clients, agentPool)
- if err != nil {
- return fmt.Errorf("Error updating agent pool in Azure DevOps: %+v", err)
+ // auto update can only be set to true on creation
+ if args.Pool.AutoUpdate != nil && !*args.Pool.AutoUpdate {
+ updateArgs := taskagent.UpdateAgentPoolArgs{
+ PoolId: agentPool.Id,
+ Pool: &taskagent.TaskAgentPool{
+ Name: args.Pool.Name,
+ PoolType: args.Pool.PoolType,
+ AutoProvision: args.Pool.AutoProvision,
+ AutoUpdate: args.Pool.AutoUpdate,
+ },
}
- }
+ agentPool, err = clients.TaskAgentClient.UpdateAgentPool(clients.Ctx, updateArgs)
- flattenAzureAgentPool(d, createdAgentPool)
+ if err := syncStatus(updateArgs, clients); err != nil {
+ return err
+ }
+ if err != nil {
+ return fmt.Errorf(" updating agent pool in Azure DevOps: %+v", err)
+ }
+ }
+ d.SetId(strconv.Itoa(*agentPool.Id))
return resourceAzureAgentPoolRead(d, m)
}
func resourceAzureAgentPoolRead(d *schema.ResourceData, m interface{}) error {
+ clients := m.(*client.AggregatedClient)
+
poolID, err := strconv.Atoi(d.Id())
if err != nil {
- return fmt.Errorf("Error getting agent pool Id: %+v", err)
+ return fmt.Errorf(" parse agent pool ID: %+v", err)
}
- clients := m.(*client.AggregatedClient)
- agentPool, err := azureAgentPoolRead(clients, poolID)
+ agentPool, err := clients.TaskAgentClient.GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{PoolId: &poolID})
if err != nil {
if utils.ResponseWasNotFound(err) {
d.SetId("")
return nil
}
- return fmt.Errorf("Error looking up agent pool with ID %d. Error: %v", poolID, err)
+ return fmt.Errorf(" looking up Agent Pool with ID %d. Error: %v", poolID, err)
}
- flattenAzureAgentPool(d, agentPool)
+ d.Set("name", agentPool.Name)
+ d.Set("pool_type", agentPool.PoolType)
+ d.Set("auto_provision", agentPool.AutoProvision)
+
+ if agentPool.AutoUpdate != nil {
+ d.Set("auto_update", agentPool.AutoUpdate)
+ }
return nil
}
func resourceAzureAgentPoolUpdate(d *schema.ResourceData, m interface{}) error {
clients := m.(*client.AggregatedClient)
- agentPool, err := expandAgentPool(d, false)
- if err != nil {
- return fmt.Errorf("Error converting terraform data model to AzDO agent pool reference: %+v", err)
+
+ parameter := taskagent.UpdateAgentPoolArgs{
+ Pool: &taskagent.TaskAgentPool{
+ Name: converter.String(d.Get("name").(string)),
+ PoolType: converter.ToPtr(taskagent.TaskAgentPoolType(d.Get("pool_type").(string))),
+ AutoProvision: converter.Bool(d.Get("auto_provision").(bool)),
+ AutoUpdate: converter.Bool(d.Get("auto_update").(bool)),
+ },
}
- _, err = azureAgentPoolUpdate(clients, agentPool)
+ poolID, err := strconv.Atoi(d.Id())
if err != nil {
- return fmt.Errorf("Error updating agent pool in Azure DevOps: %+v", err)
+ return fmt.Errorf(" getting agent pool Id: %+v", err)
+ }
+ parameter.PoolId = &poolID
+
+ if _, err = clients.TaskAgentClient.UpdateAgentPool(clients.Ctx, parameter); err != nil {
+ return fmt.Errorf(" updating agent pool in Azure DevOps: %+v", err)
+ }
+
+ if err := syncStatus(parameter, clients); err != nil {
+ return err
}
return resourceAzureAgentPoolRead(d, m)
@@ -118,70 +164,68 @@ func resourceAzureAgentPoolUpdate(d *schema.ResourceData, m interface{}) error {
func resourceAzureAgentPoolDelete(d *schema.ResourceData, m interface{}) error {
poolID, err := strconv.Atoi(d.Id())
if err != nil {
- return fmt.Errorf("Error getting agent pool Id: %+v", err)
+ return fmt.Errorf(" parse agent pool ID: %+v", err)
}
clients := m.(*client.AggregatedClient)
- return clients.TaskAgentClient.DeleteAgentPool(clients.Ctx, taskagent.DeleteAgentPoolArgs{
- PoolId: &poolID,
- })
-}
-
-func createAzureAgentPool(clients *client.AggregatedClient, agentPool *taskagent.TaskAgentPool) (*taskagent.TaskAgentPool, error) {
- args := taskagent.AddAgentPoolArgs{
- Pool: agentPool,
+ if err := clients.TaskAgentClient.DeleteAgentPool(clients.Ctx, taskagent.DeleteAgentPoolArgs{PoolId: &poolID}); err != nil {
+ return err
}
- newTaskAgent, err := clients.TaskAgentClient.AddAgentPool(clients.Ctx, args)
- return newTaskAgent, err
-}
-
-func azureAgentPoolRead(clients *client.AggregatedClient, poolID int) (*taskagent.TaskAgentPool, error) {
- return clients.TaskAgentClient.GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{
- PoolId: &poolID,
- })
-}
-
-func azureAgentPoolUpdate(clients *client.AggregatedClient, agentPool *taskagent.TaskAgentPool) (*taskagent.TaskAgentPool, error) {
- return clients.TaskAgentClient.UpdateAgentPool(
- clients.Ctx,
- taskagent.UpdateAgentPoolArgs{
- PoolId: agentPool.Id,
- Pool: &taskagent.TaskAgentPool{
- Name: agentPool.Name,
- PoolType: agentPool.PoolType,
- AutoProvision: agentPool.AutoProvision,
- AutoUpdate: agentPool.AutoUpdate,
- },
- })
-}
-
-func flattenAzureAgentPool(d *schema.ResourceData, agentPool *taskagent.TaskAgentPool) {
- d.SetId(strconv.Itoa(*agentPool.Id))
- d.Set("name", converter.ToString(agentPool.Name, ""))
- d.Set("pool_type", *agentPool.PoolType)
- d.Set("auto_provision", *agentPool.AutoProvision)
-
- if agentPool.AutoUpdate != nil {
- d.Set("auto_update", *agentPool.AutoUpdate)
+ // waiting resource deleted
+ stateConf := &resource.StateChangeConf{
+ Pending: []string{"Waiting"},
+ Target: []string{"Synched"},
+ Refresh: func() (interface{}, string, error) {
+ state := "Waiting"
+ agentPool, err := clients.TaskAgentClient.GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{PoolId: &poolID})
+ if err != nil {
+ if utils.ResponseWasNotFound(err) {
+ state = "Synched"
+ } else {
+ return nil, "", fmt.Errorf(" looking up Agent Pool with ID: %+v", err)
+ }
+ }
+ if agentPool == nil {
+ state = "Synched"
+ }
+ return state, state, nil
+ },
+ Timeout: 5 * time.Minute,
+ MinTimeout: 3 * time.Second,
+ Delay: 1 * time.Second,
+ ContinuousTargetOccurence: 2,
+ }
+ if _, err := stateConf.WaitForStateContext(clients.Ctx); err != nil {
+ return fmt.Errorf(" waiting for Agent Pool deleted. %v ", err)
}
+ return nil
}
-func expandAgentPool(d *schema.ResourceData, forCreate bool) (*taskagent.TaskAgentPool, error) {
- poolID, err := strconv.Atoi(d.Id())
- if !forCreate && err != nil {
- return nil, fmt.Errorf("Error getting agent pool Id: %+v", err)
+func syncStatus(params taskagent.UpdateAgentPoolArgs, client *client.AggregatedClient) error {
+ stateConf := &resource.StateChangeConf{
+ Pending: []string{"Waiting"},
+ Target: []string{"Synched"},
+ Refresh: func() (interface{}, string, error) {
+ state := "Waiting"
+ agentPool, err := client.TaskAgentClient.GetAgentPool(client.Ctx, taskagent.GetAgentPoolArgs{PoolId: params.PoolId})
+ if err != nil {
+ return nil, "", fmt.Errorf(" looking up Agent Pool with ID: %+v", err)
+ }
+ if *agentPool.AutoUpdate == *params.Pool.AutoUpdate &&
+ *agentPool.AutoProvision == *params.Pool.AutoProvision &&
+ *agentPool.PoolType == *params.Pool.PoolType {
+ state = "Synched"
+ }
+ return state, state, nil
+ },
+ Timeout: 5 * time.Minute,
+ MinTimeout: 3 * time.Second,
+ Delay: 1 * time.Second,
+ ContinuousTargetOccurence: 2,
}
-
- poolType := taskagent.TaskAgentPoolType(d.Get("pool_type").(string))
-
- pool := &taskagent.TaskAgentPool{
- Id: &poolID,
- Name: converter.String(d.Get("name").(string)),
- PoolType: &poolType,
- AutoProvision: converter.Bool(d.Get("auto_provision").(bool)),
- AutoUpdate: converter.Bool(d.Get("auto_update").(bool)),
+ if _, err := stateConf.WaitForStateContext(client.Ctx); err != nil {
+ return fmt.Errorf(" waiting for Agent Pool ready. %v ", err)
}
-
- return pool, nil
+ return nil
}
diff --git a/azuredevops/internal/service/taskagent/resource_agentpool_test.go b/azuredevops/internal/service/taskagent/resource_agentpool_test.go
deleted file mode 100644
index bafd0c3b..00000000
--- a/azuredevops/internal/service/taskagent/resource_agentpool_test.go
+++ /dev/null
@@ -1,172 +0,0 @@
-//go:build (all || resource_agentpool) && !exclude_resource_agentpool
-// +build all resource_agentpool
-// +build !exclude_resource_agentpool
-
-package taskagent
-
-// The tests in this file use the mock clients in mock_client.go to mock out
-// the Azure DevOps client operations.
-
-import (
- "context"
- "errors"
- "fmt"
- "math/rand"
- "testing"
-
- "github.com/golang/mock/gomock"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
- "github.com/microsoft/azure-devops-go-api/azuredevops/v6/taskagent"
- "github.com/microsoft/terraform-provider-azuredevops/azdosdkmocks"
- "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client"
- "github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter"
- "github.com/stretchr/testify/require"
-)
-
-var testAgentPoolID = rand.Intn(100)
-
-var testAgentPool = taskagent.TaskAgentPool{
- Id: &testAgentPoolID,
- Name: converter.String("Name"),
- PoolType: &taskagent.TaskAgentPoolTypeValues.Automation,
- AutoProvision: converter.Bool(false),
-}
-
-// verifies that the flatten/expand round trip yields the same agent pool definition
-func TestAgentPool_ExpandFlatten_Roundtrip(t *testing.T) {
- resourceData := schema.TestResourceDataRaw(t, ResourceAgentPool().Schema, nil)
- flattenAzureAgentPool(resourceData, &testAgentPool)
-
- agentPoolAfterRoundTrip, err := expandAgentPool(resourceData, true)
- require.Nil(t, err)
- require.Equal(t, testAgentPool, *agentPoolAfterRoundTrip)
-}
-
-// verifies that the create operation is considered failed if the API call fails.
-func TestAgentPool_CreateAgentPool_DoesNotSwallowErrorFromFailedAddAgentCall(t *testing.T) {
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
-
- taskAgentClient := azdosdkmocks.NewMockTaskagentClient(ctrl)
- clients := &client.AggregatedClient{
- TaskAgentClient: taskAgentClient,
- Ctx: context.Background(),
- }
-
- expectedProjectCreateArgs := taskagent.AddAgentPoolArgs{
- Pool: &testAgentPool,
- }
-
- taskAgentClient.
- EXPECT().
- AddAgentPool(clients.Ctx, expectedProjectCreateArgs).
- Return(nil, errors.New("AddAgentPool() Failed")).
- Times(1)
-
- newTaskAgentPool, err := createAzureAgentPool(clients, &testAgentPool)
- require.Nil(t, newTaskAgentPool)
- require.Equal(t, "AddAgentPool() Failed", err.Error())
-}
-
-func TestAgentPool_DeleteAgentPool_ReturnsErrorIfIdReadFails(t *testing.T) {
- client := &client.AggregatedClient{}
-
- resourceData := schema.TestResourceDataRaw(t, ResourceAgentPool().Schema, nil)
- flattenAzureAgentPool(resourceData, &testAgentPool)
- resourceData.SetId("")
-
- err := resourceAzureAgentPoolDelete(resourceData, client)
- require.Equal(t, "Error getting agent pool Id: strconv.Atoi: parsing \"\": invalid syntax", err.Error())
-}
-
-func TestAgentPool_UpdateAgentPool_ReturnsErrorIfIdReadFails(t *testing.T) {
- client := &client.AggregatedClient{}
-
- resourceData := schema.TestResourceDataRaw(t, ResourceAgentPool().Schema, nil)
- flattenAzureAgentPool(resourceData, &testAgentPool)
- resourceData.SetId("")
-
- err := resourceAzureAgentPoolUpdate(resourceData, client)
- require.Equal(t, "Error converting terraform data model to AzDO agent pool reference: Error getting agent pool Id: strconv.Atoi: parsing \"\": invalid syntax", err.Error())
-}
-
-func TestAgentPool_UpdateAgentPool_UpdateAndRead(t *testing.T) {
- ctrl := gomock.NewController(t)
- defer ctrl.Finish()
-
- taskAgentClient := azdosdkmocks.NewMockTaskagentClient(ctrl)
- clients := &client.AggregatedClient{
- TaskAgentClient: taskAgentClient,
- Ctx: context.Background(),
- }
-
- agentToUpdate := taskagent.TaskAgentPool{
- Id: &testAgentPoolID,
- Name: converter.String("Foo"),
- PoolType: &taskagent.TaskAgentPoolTypeValues.Deployment,
- AutoProvision: converter.Bool(true),
- AutoUpdate: converter.Bool(true),
- }
-
- resourceData := schema.TestResourceDataRaw(t, ResourceAgentPool().Schema, nil)
- flattenAzureAgentPool(resourceData, &agentToUpdate)
-
- taskAgentClient.
- EXPECT().
- UpdateAgentPool(clients.Ctx, taskagent.UpdateAgentPoolArgs{
- PoolId: &testAgentPoolID,
- Pool: &taskagent.TaskAgentPool{
- Name: agentToUpdate.Name,
- PoolType: agentToUpdate.PoolType,
- AutoProvision: agentToUpdate.AutoProvision,
- AutoUpdate: agentToUpdate.AutoUpdate,
- },
- }).
- Return(&agentToUpdate, nil).
- Times(1)
-
- taskAgentClient.
- EXPECT().
- GetAgentPool(clients.Ctx, taskagent.GetAgentPoolArgs{
- PoolId: &testAgentPoolID,
- }).
- Return(&agentToUpdate, nil).
- Times(1)
-
- err := resourceAzureAgentPoolUpdate(resourceData, clients)
- require.Nil(t, err)
-
- updatedTaskAgent, _ := expandAgentPool(resourceData, false)
- require.Equal(t, agentToUpdate.Id, updatedTaskAgent.Id)
- require.Equal(t, agentToUpdate.Name, updatedTaskAgent.Name)
- require.Equal(t, agentToUpdate.PoolType, updatedTaskAgent.PoolType)
- require.Equal(t, agentToUpdate.AutoProvision, updatedTaskAgent.AutoProvision)
- require.Equal(t, agentToUpdate.AutoUpdate, updatedTaskAgent.AutoUpdate)
-}
-
-// validates supported pool types are allowed by the schema
-func TestAgentPoolDefinition_PoolTypeIsCorrect(t *testing.T) {
- validPoolTypes := []string{
- string(taskagent.TaskAgentPoolTypeValues.Automation),
- string(taskagent.TaskAgentPoolTypeValues.Deployment),
- }
- poolTypeSchema := ResourceAgentPool().Schema["pool_type"]
-
- for _, repoType := range validPoolTypes {
- _, errors := poolTypeSchema.ValidateFunc(repoType, "")
- require.Equal(t, 0, len(errors), "Agent pool type unexpectedly did not pass validation")
- }
-}
-
-// validates invalid pool types are rejected by the schema
-func TestAgentPoolDefinition_WhenPoolTypeIsNotCorrect_ReturnsError(t *testing.T) {
- invalidPoolTypes := []string{"", "unknown"}
- poolTypeSchema := ResourceAgentPool().Schema["pool_type"]
-
- for _, poolType := range invalidPoolTypes {
- _, errors := poolTypeSchema.ValidateFunc(poolType, "pool_type")
- expectedError := fmt.Sprintf("expected pool_type to be one of [automation deployment], got %s", poolType)
- require.Equal(t, 1, len(errors), "Agent pool type %v unexpectedly passed validation", poolType)
- require.Equal(t, expectedError, errors[0].Error())
- }
-}
diff --git a/azuredevops/internal/utils/converter/converter.go b/azuredevops/internal/utils/converter/converter.go
index dd17e710..6f66a4e0 100644
--- a/azuredevops/internal/utils/converter/converter.go
+++ b/azuredevops/internal/utils/converter/converter.go
@@ -33,6 +33,10 @@ func Int(value int) *int {
return &value
}
+func ToPtr[E any](e E) *E {
+ return &e
+}
+
// ASCIIToIntPtr Convert a string to an Int Pointer
func ASCIIToIntPtr(value string) (*int, error) {
i, err := strconv.Atoi(value)