-
Notifications
You must be signed in to change notification settings - Fork 102
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
Refactor data retention policy endpoints to allow polymorphic DRP types #844
Conversation
// SetDataRetentionPolicy sets an organization's data retention policy | ||
// **Note: This functionality is only available in Terraform Enterprise.** | ||
// DEPRECATED: Use SetDataRetentionPolicyDeleteOlder instead | ||
// **Note: This functionality is only available in Terraform Enterprise versions v202311-1 and v202312-1.** | ||
SetDataRetentionPolicy(ctx context.Context, organization string, options DataRetentionPolicySetOptions) (*DataRetentionPolicy, 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.
This creates three different functions for creating the three different types of DRP.
An alternative approach would be to have one function which accepts some kind of enum to specify which type of DRP should be created....maybe the DataRetentionPolicySetOptions would contain the type, and then optionally the different attributes for the different types of DRP.
I went for more explicit function signatures, but open to feedback
// tell the current jsonapi implementation that the direct result of an endpoint could be different types. Relationships can be polymorphic, | ||
// but the direct result of an endpoint can't be (as far as the jsonapi implementation is concerned) |
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 potentially something we could improve in the jsonapi fork...it would be useful to specify that the direct result of an API (not just a relationship) is polymorphic, and should populate a choice type.
Im not sure exactly what that would look like...maybe we would also need an UnmarshalPolymorphicPayload
function. Or we could add some sort of tag to the choice type (DataRetentionPolicyChoice
) to indicate that it should be treated as polymorphic...something like:
type DataRetentionPolicyChoice struct {
Type string `jsonapi:"primary,polymorphic"`
DataRetentionPolicy *DataRetentionPolicy
DataRetentionPolicyDeleteOlder *DataRetentionPolicyDeleteOlder
DataRetentionPolicyDontDelete *DataRetentionPolicyDontDelete
}
organization.go
Outdated
|
||
// there is no drp (of a known type) | ||
if org.DataRetentionPolicy == nil || !org.DataRetentionPolicy.IsPopulated() { | ||
return org.DataRetentionPolicy, 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.
I am not sure if this should be like this, where we return a nil or empty *DataRetentionPolicyChoice
if the org has no DRP....or if we should return a ResourceNotFound
error. Open to feedback
I have confirmed that this still allows for management of data retention policies on TFE v202312-1...the deprecated |
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 concern is that this is a breaking change to the package API because it was never labeled as beta (and subject to change)
But I also note that this endpoint doesn't appear to be documented at all? Changes to go-tfe presume API changes will follow the stability policy which usually means that we would add an additional method to deal with the new responses, while maintaining the old ones until fully deprecated. Was the stability policy overlooked because it was not documented? Maybe you can tell me more. Nevertheless, the semver of go-tfe reflects the API of the public interfaces, so we have to do something bad. Here are some potential options:
- We could just rev the version of go-tfe to 2.0. I don't mind this and tbh it could be good since we could align with 'TFC API v2' The downside is that we haven't yet identified other breaking changes that we'd like to include.
- We could deprecate the existing method but otherwise leave it unchanged, but this has several downsides: it introduces confusing naming, plus it's not only deprecated but literally broken in all but two versions of TFE.
Interested in your thoughts
Thanks Brandon, definitely agreed that the backward compatibility breaking is the biggest concern here.
We could definitely change this to leave the signature of the ReadDataRetentionPolicy methods unchanged, and add a new That would still leave the issue with the organization and workspace relationships to a data-retention-policy. If we leave the type of that relationship unchanged ( I can fiddle with it to see what I can get working, but let me know what you think about making those relationships backwards compatible |
I am in the process of adding API documentation for updating data retention policies through the API. Specifically, the documentation includes information on the different types of data retention policies. |
329f63b
to
b09895a
Compare
API docs for data retention policies now exist for workspaces, organizations, and for the different types of DRPs.
@brandonc I have also made a quick alternate version of this which maintains the existing Im personally not sure which option is better...the one represented in this PR has a cleaner final design, but is a bit worse for backward compatibility, though neither are perfect. Let me know what you think! |
b09895a
to
8152a68
Compare
I found a way to maintain backward compatibility on the I have maintained the existing To maintain the |
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.
Just a few code observations for now. Great work keeping backwards compatibility
organization.go
Outdated
// **Note: This functionality is only available in Terraform Enterprise.** | ||
ReadDataRetentionPolicyV2(ctx context.Context, organization string) (*DataRetentionPolicyChoice, 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.
Just pointing out that this is the first time we've revised an interface method with "V2" and it's worth considering other naming since it would be nice to reserve the right to imply version specifiers as they relate to the platform API version.
Other options (just spitballing)
- Create a new interface tfe.DataRetentionPolicies with Read and Set... methods.
- ReadDataRetentionPolicy2 (The lack of a V is a minor difference but could subtly suggest that it's not related to a semantic version of something)
- ReadDataRetentionPolicyChoice (reflects the new return type but is mostly meaningless naming)
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.
A potential problem with the new interface (if I am understanding you idea correctly), is that we will also support policies at different levels (admin, project). Admin data retention policies exist, but you cant set "dont delete" policies at that level. So making the AdminGeneralSetting
struct implement tfe.DataRetentionPolicies
would involve implementing the SetDataRetentionPolicyDontDelete
function....which would be not supported.
Maybe not a deal breaker, but a potential reason not to go that route.
Of those choices I would lean ReadDataRetentionPolicyChoice
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 have updated this to ReadDataRetentionPolicyChoice
instead
Co-authored-by: Brandon Croft <brandon.croft@gmail.com>
6870298
to
a646d85
Compare
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.
💯
Reminder to the contributor that merged this PR: if your changes have added important functionality or fixed a relevant bug, open a follow-up PR to update CHANGELOG.md with a note on your changes. |
Description
The data retention policy APIs (a TFE only feature) in the 202401-1 TFE Release have be updated return polymorphic data retention policy types.
Previously the workspace and organization (TFE versions v202311-1 and v202312-1) had a
data-retention-policy
relationship which would contain adata-retention-policies
type. The workspace and org/relationships/data-retention-policy
endpoint was used to read and update the drp, accepting and returning thedata-retention-policies
type.In TFE version v202401-1, the TFC/E backend no longer returns a
data-retention-policies
type, instead it uses different types for different drp settings. There is adata-retention-policy-delete-olders
for drps which should delete data after N days, anddata-retention-policy-dont-deletes
for drps which explicitly specify that data should be retained. DRPs can also be null if the workspace/org should inherit a parent DRP.This causes a failure in go-tfe when trying to read an organization or workspace which contains a DRP from TFE v202401-1, because the returned relationship type value (eg.
data-retention-policy-delete-olders
) doesnt match what go-tfe expects (data-retention-policies
).To fix this, we need to change the DRP relationships to be
polyrelation
. Now the relationship on orgs and workspaces, and the DRP read functions, will return a choice type (DataRetentionPolicyChoice
) with one populated field containing the DRP.For updating DRPs, organizations and workspaces have separate functions for setting each type of DRP (
SetDataRetentionPolicyDeleteOlder
andSetDataRetentionPolicyDontDelete
).In terms of backward compatibility, the "legacy"
DataRetentionPolicy
type has been retained as one of the options for the polymorphic relationship, and has been marked as deprecated. Similarly the workspace and organization interfaceSetDataRetentionPolicy
function has been maintained, but it will only work with TFE versions v202311-1 and v202312-1...newer TFE versions will need to use the new type specific functions (SetDataRetentionPolicyDeleteOlder
andSetDataRetentionPolicyDontDelete
).However, older versions of go-tfe will fail to read DRPs from TFE v202401-1 and newer, when they encounter the
data-retention-policy-delete-olders
type from the server.Testing plan
ReadDataRetentionPolicy
functionSetDataRetentionPolicyDeleteOlder
andSetDataRetentionPolicyDontDelete
respectively. This can update the current drp to have a different value (eg the number of days to delete after), or it can update the type of the DRP (from delete older to dont delete, or vice versa)DeleteDataRetentionPolicy
function, which sets the backend to inherit the parent DRPSetDataRetentionPolicy
can still be used to update the DRPOutput from tests
Including output from tests may require access to a TFE instance. Ignore this section if you have no environment to test against.
JIRA