-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: env0_aws_credentials - apply after import will delete+create #371
Conversation
client/cloud_credentials.go
Outdated
@@ -37,7 +33,7 @@ type AwsCredentialsCreatePayload struct { | |||
} | |||
|
|||
type AwsCredentialsValuePayload struct { | |||
RoleArn string `json:"roleArn"` | |||
RoleArn string `json:"roleArn" resource:"arn"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new tag type for serialization. See usage below.
(Basically in terraform the resource is "arn" and not "role_arn" - so needed to resolve this).
@@ -89,7 +85,7 @@ func (client *ApiClient) CloudCredentials(id string) (Credentials, error) { | |||
} | |||
} | |||
|
|||
return Credentials{}, fmt.Errorf("CloudCredentials: [%s] not found ", id) | |||
return Credentials{}, &NotFoundError{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used to handle drift later.
"github.com/google/uuid" | ||
) | ||
|
||
func getCredentialsByName(name string, prefix string, meta interface{}) (client.Credentials, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Common helper functions for credentials (can be used by GCP and Azure in the future). (In case import is added to them as well).
@@ -61,7 +61,7 @@ func dataNotificationRead(ctx context.Context, d *schema.ResourceData, meta inte | |||
} | |||
|
|||
if err := writeResourceData(notification, d); err != nil { | |||
diag.Errorf("schema resource data serialization failed: %v", err) | |||
return diag.Errorf("schema resource data serialization failed: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are a few places with the same bug...
@@ -27,7 +30,6 @@ func resourceAwsCredentials() *schema.Resource { | |||
Optional: true, | |||
ForceNew: true, | |||
ConflictsWith: []string{"access_key_id"}, | |||
ExactlyOneOf: []string{"access_key_id"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "ExactlyOneOf" cannot be enforced in the schema level. (Will fail on import).
(Enforced in the code level).
@@ -62,29 +63,32 @@ func resourceAwsCredentials() *schema.Resource { | |||
} | |||
|
|||
func resourceAwsCredentialsCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | |||
_, accessKeyExist := d.GetOk("access_key_id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforcing the exactlyOnce in the code level only for creation (not for read/import).
} | ||
if externalId, ok := d.GetOk("external_id"); ok { | ||
value.ExternalId = externalId.(string) | ||
if err := readResourceData(&value, d); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some small refactoring (less lines of code).
env0/utils.go
Outdated
fieldNameSC := toSnakeCase(fieldName) | ||
if resFieldName, ok := val.Type().Field(i).Tag.Lookup("resource"); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the new tag I created (resource). Ping me if this is still unclear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool 👏
Just wondering together with you whether resourcee
is a decent tag name or we can come up with a better name. Maybe something that indicates that this is related to the TF schema would do better.
Also - WDYT about adding some note regarding it in DEVELOPMENT.md
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes and yes.
How about tfschema or tfresource ? (I'm bad with names).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both are better. If you want me to choose then I'd go with tfschema
😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a winner (:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
@@ -91,6 +91,24 @@ func TestReadResourceDataNotification(t *testing.T) { | |||
assert.Equal(t, expectedPayload, payload) | |||
} | |||
|
|||
func TestReadResourceDataWithTag(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test for the new resource tag (hopefully this test helps clarify it).
@@ -108,7 +116,7 @@ func TestUnitAwsCredentialsResource(t *testing.T) { | |||
Steps: []resource.TestStep{ | |||
{ | |||
Config: resourceConfigCreate(resourceType, resourceName, mutuallyExclusiveErrorResource), | |||
ExpectError: regexp.MustCompile("only one of `access_key_id,arn` can be specified"), | |||
ExpectError: regexp.MustCompile(`"external_id": conflicts with access_key_id`), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are multiple errors., the following just come before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Left some few minor comments
env0/resource_aws_credentials.go
Outdated
d.Set("name", credentials.Name) | ||
d.SetId(credentials.Id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the seralization logic here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah sure. In general, I use it when there a multiple fields.
Either way is fine by me. I'll fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think always using it makes a lot of sense since we wouldn't need to change anything when we'll add a new field 💪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
env0/utils.go
Outdated
fieldNameSC := toSnakeCase(fieldName) | ||
if resFieldName, ok := val.Type().Field(i).Tag.Lookup("resource"); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool 👏
Just wondering together with you whether resourcee
is a decent tag name or we can come up with a better name. Maybe something that indicates that this is related to the TF schema would do better.
Also - WDYT about adding some note regarding it in DEVELOPMENT.md
?
@@ -14,6 +15,8 @@ func resourceAwsCredentials() *schema.Resource { | |||
ReadContext: resourceAwsCredentialsRead, | |||
DeleteContext: resourceAwsCredentialsDelete, | |||
|
|||
Importer: &schema.ResourceImporter{StateContext: resourceAwsCredentialsImport}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TomerHeber if we're already at it, can we perhaps also support import for all other credentials type? I'd do it in a separate PR tho
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keeping the issue open.
ebd19fc
to
7d06da7
Compare
I'm keeping open, to adding support for other credential types.
Solution
Added import.
Removed a schema requirements and instead enforce during read.
Added acceptance tests.
Added a "resource" tag.
Added import examples.
Fixed some other issues I noticed.