Skip to content

Commit 64c1537

Browse files
authored
Gitlab enterprise polling (#129)
* implement polling of gitlab enterprise repo to handle lengthy sync phase during onboarding * add docs * use interval as const
1 parent 0a541bb commit 64c1537

File tree

6 files changed

+89
-6
lines changed

6 files changed

+89
-6
lines changed

client/models.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,21 @@ type RepoUpdate struct {
560560
Agents []string `json:"agents"`
561561
UseAllAgents bool `json:"use_all_agents"`
562562
}
563+
564+
type RepoDetails struct {
565+
Name string `json:"name"`
566+
URL string `json:"repository_url"`
567+
Token *string `json:"token"`
568+
Branch string `json:"branch"`
569+
CredentialName string `json:"credential_name"`
570+
UseAllAgents bool `json:"use_all_agents"`
571+
Agents []Agents `json:"agents"`
572+
Status string `json:"status"`
573+
SpaceName string `json:"space_name"`
574+
Errors []Error `json:"errors"`
575+
}
576+
577+
type Agents struct {
578+
Name string `json:"name"`
579+
Status string `json:"status"`
580+
}

client/repository.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,27 @@ func (c *Client) UpdateRepoConfiguration(space_name string, repo_name string, cr
188188

189189
return nil
190190
}
191+
192+
func (c *Client) GetRepoDetails(space_name string, repo_name string) (*RepoDetails, error) {
193+
req, err := http.NewRequest("GET", fmt.Sprintf("%sapi/spaces/%s/repositories", c.HostURL, space_name), nil)
194+
if err != nil {
195+
return nil, err
196+
}
197+
body, err := c.doRequest(req, &c.Token)
198+
if err != nil {
199+
return nil, err
200+
}
201+
repos := []RepoDetails{}
202+
err = json.Unmarshal(body, &repos)
203+
if err != nil {
204+
return nil, err
205+
}
206+
repo := RepoDetails{}
207+
for _, repo_item := range repos {
208+
if repo_name == repo_item.Name {
209+
repo = repo_item
210+
return &repo, nil
211+
}
212+
}
213+
return nil, fmt.Errorf("repository %s not found", repo_name)
214+
}

docs/resources/gitlab_enterprise_repository_space_association.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ resource "torque_gitlab_enterprise_repository_space_association" "repository" {
3636
credential_name = "credentials"
3737
use_all_agents = false
3838
agents = ["eks", "aks"]
39+
timeout = 5
3940
}
4041
```
4142

@@ -53,5 +54,6 @@ resource "torque_gitlab_enterprise_repository_space_association" "repository" {
5354
### Optional
5455

5556
- `agents` (List of String) List of specific agents to use to onboard and sync this repository. Cannot be specified when use_all_agents is true.
57+
- `timeout` (Number) Time in minutes to wait for Torque to sync the repository during the onboarding. Default is 1 minute.
5658
- `token` (String, Deprecated) Authentication Token to the project/repository. If omitted, existing credentials provided in the credential_name field will be used for authentication. If provided, a new credentials object will be created.
5759
- `use_all_agents` (Boolean) Whether all associated agents can be used to onboard and sync this repository. Must be set to false if agents attribute is used.

examples/resources/torque_gitlab_enterprise_repository_space_association/resource.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ resource "torque_gitlab_enterprise_repository_space_association" "repository" {
2121
credential_name = "credentials"
2222
use_all_agents = false
2323
agents = ["eks", "aks"]
24+
timeout = 5
2425
}

examples/resources/torque_gitlab_enterprise_repository_space_association/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ variable "agents" {
5555
type = string
5656
description = "List of specific agents to use to onboard and sync this repository. Cannot be specified when use_all_agents is true."
5757
}
58+
59+
variable "timeout" {
60+
type = number
61+
description = "Time in minutes to wait for Torque to sync the repository during the onboarding. Default is 1 minute."
62+
default = 1
63+
}

internal/provider/resources/space_gitlab_enterprise_repository_resource.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ import (
44
"context"
55
"fmt"
66
"strings"
7+
"time"
78

89
"github.com/hashicorp/terraform-plugin-framework/path"
910
"github.com/hashicorp/terraform-plugin-framework/resource"
1011
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
1112
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
13+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int32default"
1214
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1315
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1416
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1517
"github.com/hashicorp/terraform-plugin-framework/types"
16-
"github.com/hashicorp/terraform-plugin-log/tflog"
1718
"github.com/qualitorque/terraform-provider-torque/client"
1819
)
1920

@@ -39,6 +40,7 @@ type TorqueSpaceGitlabEnterpriseRepositoryResourceModel struct {
3940
CredentialName types.String `tfsdk:"credential_name"`
4041
UseAllAgents types.Bool `tfsdk:"use_all_agents"`
4142
Agents types.List `tfsdk:"agents"`
43+
TimeOut types.Int32 `tfsdk:"timeout"`
4244
}
4345

4446
func (r *TorqueSpaceGitlabEnterpriseRepositoryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
@@ -103,6 +105,13 @@ func (r *TorqueSpaceGitlabEnterpriseRepositoryResource) Schema(ctx context.Conte
103105
Optional: true,
104106
ElementType: types.StringType,
105107
},
108+
"timeout": schema.Int32Attribute{
109+
Description: "Time in minutes to wait for Torque to sync the repository during the onboarding. Default is 1 minute.",
110+
Required: false,
111+
Optional: true,
112+
Computed: true,
113+
Default: int32default.StaticInt32(1),
114+
},
106115
},
107116
}
108117
}
@@ -129,7 +138,11 @@ func (r *TorqueSpaceGitlabEnterpriseRepositoryResource) Configure(ctx context.Co
129138

130139
func (r *TorqueSpaceGitlabEnterpriseRepositoryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
131140
var data TorqueSpaceGitlabEnterpriseRepositoryResourceModel
132-
141+
const (
142+
StatusSyncing = "Syncing"
143+
StatusConnected = "Connected"
144+
Interval = 4 * time.Second
145+
)
133146
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
134147

135148
if resp.Diagnostics.HasError() {
@@ -141,16 +154,35 @@ func (r *TorqueSpaceGitlabEnterpriseRepositoryResource) Create(ctx context.Conte
141154
agents = append(agents, strings.Trim(agent.String(), "\""))
142155
}
143156
}
157+
start := time.Now()
144158
err := r.client.OnboardGitlabEnterpriseRepoToSpace(data.SpaceName.ValueString(), data.RepositoryName.ValueString(),
145159
data.RepositoryUrl.ValueString(), data.Token.ValueStringPointer(), data.Branch.ValueString(), data.CredentialName.ValueString(), agents, data.UseAllAgents.ValueBool())
146160
if err != nil {
161+
repo, err := r.client.GetRepoDetails(data.SpaceName.ValueString(), data.RepositoryName.ValueString())
162+
if repo == nil {
163+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to onboard repository to space, got error: %s", err))
164+
return
165+
}
166+
if repo.Status == StatusSyncing {
167+
timeout := time.Duration(data.TimeOut.ValueInt32()) * time.Minute
168+
for time.Since(start) < timeout {
169+
repo, err := r.client.GetRepoDetails(data.SpaceName.ValueString(), data.RepositoryName.ValueString())
170+
if err != nil {
171+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Error while polling repository status: %s", err))
172+
return
173+
}
174+
if repo.Status == StatusConnected {
175+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
176+
return
177+
}
178+
time.Sleep(Interval)
179+
}
180+
resp.Diagnostics.AddError("Sync Timeout", "Timed out while syncing repository")
181+
return
182+
}
147183
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to onboard repository to space, got error: %s", err))
148184
return
149185
}
150-
151-
tflog.Trace(ctx, "Resource Created Successful!")
152-
153-
// Save data into Terraform state.
154186
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
155187
}
156188

0 commit comments

Comments
 (0)