Skip to content

Commit 598c90a

Browse files
fix: project-scoped credentials need to be unique (#775)
Signed-off-by: Blake Pettersson <[email protected]>
1 parent e12a69a commit 598c90a

File tree

3 files changed

+425
-8
lines changed

3 files changed

+425
-8
lines changed

internal/provider/model_repository.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ func repositorySchemaAttributes() map[string]schema.Attribute {
6666
"project": schema.StringAttribute{
6767
MarkdownDescription: "The project name, in case the repository is project scoped.",
6868
Optional: true,
69+
PlanModifiers: []planmodifier.String{
70+
stringplanmodifier.RequiresReplace(),
71+
},
6972
},
7073
"username": schema.StringAttribute{
7174
MarkdownDescription: "Username used for authenticating at the remote repository.",
@@ -188,7 +191,13 @@ func (m *repositoryModel) toAPIModel() (*v1alpha1.Repository, error) {
188191
}
189192

190193
func (m *repositoryModel) updateFromAPI(repo *v1alpha1.Repository) *repositoryModel {
191-
m.ID = types.StringValue(repo.Repo)
194+
// Generate ID using "|" separator for project-scoped repos
195+
if repo.Project != "" {
196+
m.ID = types.StringValue(repo.Repo + "|" + repo.Project)
197+
} else {
198+
m.ID = types.StringValue(repo.Repo)
199+
}
200+
192201
m.Repo = types.StringValue(repo.Repo)
193202
m.Type = types.StringValue(repo.Type)
194203
m.EnableLFS = types.BoolValue(repo.EnableLFS)

internal/provider/resource_repository.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func (r *repositoryResource) Create(ctx context.Context, req resource.CreateRequ
130130
tflog.Trace(ctx, fmt.Sprintf("created repository %s", createdRepo.Repo))
131131

132132
// Save data into Terraform state
133-
resp.Diagnostics.Append(resp.State.Set(ctx, data.updateFromAPI(repo))...)
133+
resp.Diagnostics.Append(resp.State.Set(ctx, data.updateFromAPI(createdRepo))...)
134134

135135
// Perform a read to get the latest state with connection status
136136
if !resp.Diagnostics.HasError() {
@@ -156,7 +156,7 @@ func (r *repositoryResource) Read(ctx context.Context, req resource.ReadRequest,
156156
}
157157

158158
// Read repository from API
159-
repo, diags := r.readRepository(ctx, data.ID.ValueString(), data.Project.ValueString())
159+
repo, diags := r.readRepository(ctx, data.Repo.ValueString(), data.Project.ValueString())
160160
resp.Diagnostics.Append(diags...)
161161

162162
if resp.Diagnostics.HasError() {
@@ -261,23 +261,36 @@ func (r *repositoryResource) Delete(ctx context.Context, req resource.DeleteRequ
261261
_, err := r.si.RepositoryClient.DeleteRepository(
262262
ctx,
263263
&repository.RepoQuery{
264-
Repo: data.ID.ValueString(),
264+
Repo: data.Repo.ValueString(),
265265
AppProject: data.Project.ValueString(),
266266
},
267267
)
268268

269269
if err != nil {
270270
if !strings.Contains(err.Error(), "NotFound") {
271-
resp.Diagnostics.Append(diagnostics.ArgoCDAPIError("delete", "repository", data.ID.ValueString(), err)...)
271+
resp.Diagnostics.Append(diagnostics.ArgoCDAPIError("delete", "repository", data.Repo.ValueString(), err)...)
272272
return
273273
}
274274
}
275275

276-
tflog.Trace(ctx, fmt.Sprintf("deleted repository %s", data.ID.ValueString()))
276+
tflog.Trace(ctx, fmt.Sprintf("deleted repository %s", data.Repo.ValueString()))
277277
}
278278

279279
func (r *repositoryResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
280-
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
280+
// Import ID format can be:
281+
// - "repo_url" for global repositories
282+
// - "repo_url|project_name" for project-scoped repositories
283+
idParts := strings.SplitN(req.ID, "|", 2)
284+
285+
repoURL := idParts[0]
286+
287+
// Set repo attribute
288+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("repo"), repoURL)...)
289+
290+
// Only set project if it was provided in the import ID
291+
if len(idParts) == 2 && idParts[1] != "" {
292+
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project"), idParts[1])...)
293+
}
281294
}
282295

283296
func (r *repositoryResource) readRepository(ctx context.Context, repoURL, project string) (*v1alpha1.Repository, diag.Diagnostics) {
@@ -294,8 +307,11 @@ func (r *repositoryResource) readRepository(ctx context.Context, repoURL, projec
294307

295308
if repos != nil {
296309
for _, repo := range repos.Items {
297-
if repo.Repo == repoURL {
310+
// Match both URL and project to handle cases where the same repo URL
311+
// exists in multiple projects
312+
if repo.Repo == repoURL && repo.Project == project {
298313
finalRepo = repo
314+
break
299315
}
300316
}
301317
}

0 commit comments

Comments
 (0)