Remove deleted resources and datasources from Terraform state on Read (all remaining services) (#346)

* Remove deleted resources and datasources from state on Read

* Simplify code

* Fix function description

Co-authored-by: Diogo Ferrão <diogo.ferrao@freiheit.com>

* Fix function description

Co-authored-by: Diogo Ferrão <diogo.ferrao@freiheit.com>

* Fix whitespace

---------

Co-authored-by: Diogo Ferrão <diogo.ferrao@freiheit.com>
This commit is contained in:
João Palet 2024-04-23 08:59:43 +01:00 committed by GitHub
parent 464884cabe
commit 66d6ec2bd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 262 additions and 40 deletions

View file

@ -131,11 +131,16 @@ func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequ
ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId)
ctx = tflog.SetField(ctx, "credential_id", credentialId)
err := readCredentials(ctx, &model, r.client)
found, err := readCredentials(ctx, &model, r.client)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Finding credential: %v", err))
return
}
if !found {
resp.State.RemoveResource(ctx)
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", "Credential not found")
return
}
// Set refreshed state
diags = resp.State.Set(ctx, model)

View file

@ -240,11 +240,15 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest,
ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId)
ctx = tflog.SetField(ctx, "credential_id", credentialId)
err := readCredentials(ctx, &model, r.client)
found, err := readCredentials(ctx, &model, r.client)
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Finding credential: %v", err))
return
}
if !found {
resp.State.RemoveResource(ctx)
return
}
// Set refreshed state
diags = resp.State.Set(ctx, model)
@ -388,18 +392,18 @@ func mapFields(credentialResp *objectstorage.CreateAccessKeyResponse, model *Mod
// readCredentials gets all the existing credentials for the specified credentials group,
// finds the credential that is being read and updates the state.
// If the credential cannot be found, it throws an error
func readCredentials(ctx context.Context, model *Model, client *objectstorage.APIClient) error {
// Returns True if the credential was found, False otherwise.
func readCredentials(ctx context.Context, model *Model, client *objectstorage.APIClient) (bool, error) {
projectId := model.ProjectId.ValueString()
credentialsGroupId := model.CredentialsGroupId.ValueString()
credentialId := model.CredentialId.ValueString()
credentialsGroupResp, err := client.ListAccessKeys(ctx, projectId).CredentialsGroup(credentialsGroupId).Execute()
if err != nil {
return fmt.Errorf("getting credentials groups: %w", err)
return false, fmt.Errorf("getting credentials groups: %w", err)
}
if credentialsGroupResp == nil {
return fmt.Errorf("getting credentials groups: nil response")
return false, fmt.Errorf("getting credentials groups: nil response")
}
foundCredential := false
@ -427,15 +431,12 @@ func readCredentials(ctx context.Context, model *Model, client *objectstorage.AP
// Eg. "2027-01-02T03:04:05.000Z" = "2027-01-02T03:04:05Z"
expirationTimestamp, err := time.Parse(time.RFC3339, *credential.Expires)
if err != nil {
return fmt.Errorf("unable to parse payload expiration timestamp '%v': %w", *credential.Expires, err)
return foundCredential, fmt.Errorf("unable to parse payload expiration timestamp '%v': %w", *credential.Expires, err)
}
model.ExpirationTimestamp = types.StringValue(expirationTimestamp.Format(time.RFC3339))
}
break
}
if !foundCredential {
return fmt.Errorf("credential could not be found")
}
return nil
return foundCredential, nil
}

View file

@ -213,7 +213,8 @@ func TestReadCredentials(t *testing.T) {
tests := []struct {
description string
mockedResp *objectstorage.ListAccessKeysResponse
expected Model
expectedModel Model
expectedFound bool
getCredentialsFails bool
isValid bool
}{
@ -242,6 +243,7 @@ func TestReadCredentials(t *testing.T) {
SecretAccessKey: types.StringNull(),
ExpirationTimestamp: types.StringNull(),
},
true,
false,
true,
},
@ -276,6 +278,7 @@ func TestReadCredentials(t *testing.T) {
SecretAccessKey: types.StringNull(),
ExpirationTimestamp: types.StringValue(now.Format(time.RFC3339)),
},
true,
false,
true,
},
@ -310,6 +313,7 @@ func TestReadCredentials(t *testing.T) {
SecretAccessKey: types.StringNull(),
ExpirationTimestamp: types.StringValue(now.Format(time.RFC3339)),
},
true,
false,
true,
},
@ -321,6 +325,7 @@ func TestReadCredentials(t *testing.T) {
Model{},
false,
false,
true,
},
{
"nil_response",
@ -328,6 +333,7 @@ func TestReadCredentials(t *testing.T) {
Model{},
false,
false,
false,
},
{
"non_matching_credential",
@ -348,6 +354,7 @@ func TestReadCredentials(t *testing.T) {
Model{},
false,
false,
true,
},
{
"error_response",
@ -361,6 +368,7 @@ func TestReadCredentials(t *testing.T) {
},
},
Model{},
false,
true,
false,
},
@ -401,11 +409,11 @@ func TestReadCredentials(t *testing.T) {
}
model := &Model{
ProjectId: tt.expected.ProjectId,
CredentialsGroupId: tt.expected.CredentialsGroupId,
CredentialId: tt.expected.CredentialId,
ProjectId: tt.expectedModel.ProjectId,
CredentialsGroupId: tt.expectedModel.CredentialsGroupId,
CredentialId: tt.expectedModel.CredentialId,
}
err = readCredentials(context.Background(), model, client)
found, err := readCredentials(context.Background(), model, client)
if !tt.isValid && err == nil {
t.Fatalf("Should have failed")
}
@ -413,10 +421,14 @@ func TestReadCredentials(t *testing.T) {
t.Fatalf("Should not have failed: %v", err)
}
if tt.isValid {
diff := cmp.Diff(model, &tt.expected)
diff := cmp.Diff(model, &tt.expectedModel)
if diff != "" {
t.Fatalf("Data does not match: %s", diff)
}
if found != tt.expectedFound {
t.Fatalf("Found does not match: %v", found)
}
}
})
}