diff --git a/teamcity/importer.go b/teamcity/importer.go new file mode 100644 index 00000000..f98d3b28 --- /dev/null +++ b/teamcity/importer.go @@ -0,0 +1,32 @@ +package teamcity + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" +) + + +func subresourceImporter(readFunc schema.ReadFunc) schema.StateFunc { + return func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + var buildConfigID, resourceID string + + if n, err := fmt.Sscanf(d.Id(), "%s %s", &buildConfigID, &resourceID); err != nil { + return nil, fmt.Errorf("invalid import ID '%s' - %v", d.Id(), err) + } else if n != 2 { + return nil, fmt.Errorf("invalid import ID '%s' - Unrecognized format", d.Id()) + } + + d.SetId(resourceID) + + if err := d.Set("build_config_id", buildConfigID); err != nil { + return nil, err + } + + if err := readFunc(d, meta); err != nil { + return nil, err + } + + return []*schema.ResourceData{d}, nil + } +} diff --git a/teamcity/resource_artifact_dependency.go b/teamcity/resource_artifact_dependency.go index b87212e7..eb38681f 100644 --- a/teamcity/resource_artifact_dependency.go +++ b/teamcity/resource_artifact_dependency.go @@ -2,6 +2,7 @@ package teamcity import ( "fmt" + "strings" api "github.com/cvbarros/go-teamcity-sdk/teamcity" "github.com/hashicorp/terraform/helper/schema" @@ -14,7 +15,7 @@ func resourceArtifactDependency() *schema.Resource { Read: resourceArtifactDependencyRead, Delete: resourceArtifactDependencyDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: subresourceImporter(resourceArtifactDependencyRead), }, Schema: map[string]*schema.Schema{ @@ -101,6 +102,11 @@ func resourceArtifactDependencyRead(d *schema.ResourceData, meta interface{}) er dt, err := getArtifactDependency(client, d.Id()) if err != nil { + if strings.Contains(err.Error(), "404") { + // This dependency was deleted out-of-band + d.SetId("") + return nil + } return err } diff --git a/teamcity/resource_build_trigger_build_finish.go b/teamcity/resource_build_trigger_build_finish.go index 06a67915..f0b0284f 100644 --- a/teamcity/resource_build_trigger_build_finish.go +++ b/teamcity/resource_build_trigger_build_finish.go @@ -14,7 +14,7 @@ func resourceBuildTriggerBuildFinish() *schema.Resource { Read: resourceBuildTriggerBuildFinishRead, Delete: resourceBuildTriggerBuildFinishDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: subresourceImporter(resourceBuildTriggerBuildFinishRead), }, Schema: map[string]*schema.Schema{ diff --git a/teamcity/resource_build_trigger_schedule.go b/teamcity/resource_build_trigger_schedule.go index 584726e4..e5c91a56 100644 --- a/teamcity/resource_build_trigger_schedule.go +++ b/teamcity/resource_build_trigger_schedule.go @@ -14,7 +14,7 @@ func resourceBuildTriggerSchedule() *schema.Resource { Read: resourceBuildTriggerScheduleRead, Delete: resourceBuildTriggerScheduleDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: subresourceImporter(resourceBuildTriggerScheduleRead), }, Schema: map[string]*schema.Schema{ diff --git a/teamcity/resource_build_trigger_vcs.go b/teamcity/resource_build_trigger_vcs.go index b57d4f0c..0bbd9e7b 100644 --- a/teamcity/resource_build_trigger_vcs.go +++ b/teamcity/resource_build_trigger_vcs.go @@ -13,7 +13,7 @@ func resourceBuildTriggerVcs() *schema.Resource { Read: resourceBuildTriggerVcsRead, Delete: resourceBuildTriggerVcsDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: subresourceImporter(resourceBuildTriggerVcsRead), }, Schema: map[string]*schema.Schema{ diff --git a/teamcity/resource_snapshot_dependency.go b/teamcity/resource_snapshot_dependency.go index c602b43d..8d38a431 100644 --- a/teamcity/resource_snapshot_dependency.go +++ b/teamcity/resource_snapshot_dependency.go @@ -168,10 +168,13 @@ func setSnapshotDependencyBoolProperty(d *schema.ResourceData, p *api.Properties } func resourceSnapshotDependencyRead(d *schema.ResourceData, meta interface{}) error { - depService := meta.(*api.Client).DependencyService(d.Get("build_config_id").(string)) - - dt, err := getSnapshotDependency(depService, d.Id()) + _, dt, err := getSnapshotDependency(meta.(*api.Client), d.Id()) if err != nil { + if strings.Contains(err.Error(), "404") { + // This dependency was deleted out-of-band + d.SetId("") + return nil + } return err } @@ -187,11 +190,9 @@ func resourceSnapshotDependencyRead(d *schema.ResourceData, meta interface{}) er } func resourceSnapshotDependencyDelete(d *schema.ResourceData, meta interface{}) error { - depService := meta.(*api.Client).DependencyService(d.Get("build_config_id").(string)) - - dt, err := getSnapshotDependency(depService, d.Id()) + depService, dt, err := getSnapshotDependency(meta.(*api.Client), d.Id()) if err != nil { - if strings.Contains(err.Error(), "404 Not Found") { + if strings.Contains(err.Error(), "404") { // This dependency was deleted out-of-band return nil } @@ -201,17 +202,20 @@ func resourceSnapshotDependencyDelete(d *schema.ResourceData, meta interface{}) return depService.DeleteSnapshot(dt.ID) } -func getSnapshotDependency(depService *api.DependencyService, id string) (*api.SnapshotDependency, error) { +func getSnapshotDependency(client *api.Client, id string) (*api.DependencyService, *api.SnapshotDependency, error) { var buildConfigID, snapshotID string if n, err := fmt.Sscanf(id, snapshotIDFormat, &buildConfigID, &snapshotID); err != nil { - return nil, fmt.Errorf("invalid snapshot_dependency ID '%s' - %v", buildConfigID, err) + return nil, nil, fmt.Errorf("invalid snapshot_dependency ID '%s' - %v", id, err) } else if n != 2 { - return nil, fmt.Errorf("invalid snapshot_dependency ID '%s' - Unrecognized format", buildConfigID) + return nil, nil, fmt.Errorf("invalid snapshot_dependency ID '%s' - Unrecognized format", id) } + + depService := client.DependencyService(buildConfigID) + dt, err := depService.GetSnapshotByID(snapshotID) if err != nil { - return nil, err + return nil, nil, err } - return dt, nil + return depService, dt, nil }