-
Notifications
You must be signed in to change notification settings - Fork 47
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
feat: Fabric stream resource and data sources #844
Conversation
c4dfeea
to
a603dc5
Compare
ClientSecret: c.ClientSecret, | ||
BaseURL: c.BaseURL, | ||
} | ||
authClient := authConfig.New(ctx) |
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 you remind me why this change is needed? Continuing to use a shared auth client across all API clients would be ideal, but IIRC there's an issue with the shared client using a canceled context, maybe? We should make sure those issue details are captured somewhere so we can work on replacing or at least refactoring the Equinix oauth2-go library in a way that allows sharing auth across clients.
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.
So before we had a different change outlined in the EPT draft: https://github.com/equinix/terraform-provider-equinix/pull/745/files#diff-54c7c1af5fa8d5db4dc49f0e8e80e93ba2b1183ba4d5c9e2e5729e6deae6a3cd
We discussed a few things. One of them was if we were going to use the context in both that we should update all callers (like we are doing here) and the other was to keep the old method along with the new one.
The issue with not passing context for Framework is that there's a canceled context in the config when using the Interface methods that requires passing context to complete those flows.
My theory is that for SDKv2 they shared the same context as the config long enough that it wasn't an issue; but the change resolves that even if it was separate because each lifecycle method passes a usable context into it.
TL;DR, Framework requires context. SDKv2 didn't but changing it so that it uses it doesn't create a problem.
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.
Ah, the framework issue is the one I was thinking of. While this change replicates what is happening for framework, which means it's not necessarily introducing new behavior, my concern is that we're creating a bunch of separate auth clients that are going to be using the same client ID and secret but not using the same token. The SDKv2 clients previously shared the same auth client, which reduces the number of token requests across resources, but because of how equinix/oauth2-go
is written, the auth client needs a context. The framework doesn't have a suitable context for that, so we got those canceled context errors. It's not necessarily a problem to replicate the framework behavior in SDKv2, but going all-in on duplicate auth clients means we'll be making even more unnecessary token requests (two resources using the same client ID & secret each have to make their own token request even though their tokens will have the same permissions). Duplicate requests could become a problem (or at least a complication) if, for example, rate limits are introduced on the token endpoint. Long-term it would be preferable to change our approach to auth clients in the terraform provider so that tokens can be reused across API clients.
To be clear I'm on board with this change as-is; we might have to standardize on accepting a context anyway in order to make the optimization I described, whenever that time comes.
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.
Ok, I was able to follow this explanation through to the end on this one. Initially my confusion on context was distracting me from the token issue; I only partially understood what might have been happening. Now that I've got a better handle on the context cancellation issue the auth client separation per resource is clear.
We're on the same page now. Thank you for a very thorough explanation, @ctreatma!
} | ||
} | ||
|
||
output "stream_state" { |
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.
Do we need more outputs in this data source ?
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.
It's a resource, and no. We can limit the amount that we provide outputs in examples for maintenance reasons. We just need some display of attribute selection.
} | ||
} | ||
|
||
output "number_of_returned_streams" { |
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.
Same here. Do we need to add any other outputs here?
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.
Same explanation for output.
resource.TestCheckResourceAttr("data.equinix_fabric_streams.data_streams", "pagination.limit", "2"), | ||
resource.TestCheckResourceAttr("data.equinix_fabric_streams.data_streams", "pagination.offset", "1"), | ||
), | ||
ExpectNonEmptyPlan: true, |
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.
If the plan is empty, this test will fail. ExpectNonEmptyPlan: false
would keep it consistent with other tests (for other resources)
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 set specifically to allow the test to pass for my use case. I do expect a non-empty plan after my tests run. You can actually omit ExpectNonEmptyPlan: false
as well because that's the default value for that config item.
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.
Okay. Sounds good.
} | ||
*project = fwtypes.NewObjectValueOf[ProjectModel](ctx, &projectModel) | ||
|
||
const TIMEFORMAT = "2006-01-02T15:04:05.000Z" |
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 naming convention in Go for unexported constants is camelCase. const timeFormat
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.
Learned something new! There are other places where we use the non-idiomatic Go styling for constants so we can update them with the same reference as well.
Good to cite it also: https://google.github.io/styleguide/go/guide.html#mixedcaps
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.
If we're adopting or changing coding standards, that should be reflected in the linter settings to enforce convergence on the chosen style.
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.
Ok, so I went through this thoroughly. I was mistaken, we don't really have any other places that all caps were used for variable names. We have camelCase throughout.
Additionally, even when adding stylecheck
to the linter it doesn't care about all caps in a variable name. There isn't a Go style descriptor against all caps.
I'm going to leave it out of the linter for now, and I'll move this into the internal/fabric
package so that it can be reused, because we'll have it in several places for the Framework implementations of fabric's new resources.
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.
Update made 👍
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.
Ah, it's running through all files because of the config change...
We're bottle necking a bit here because of this. All files introduced by this change pass the linters. The files changed for config are not compliant.
I'm going to remove the linter update for this one, then add in separate PR. Then when we are poking around for one-off fixes or updates from SDKv2 to Framework we can make necessary updates. It's too much time for the current scope we're on.
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.
Opened #849
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 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.
Ah, it's running through all files because of the config change...
This is true of the make lint
task for running linters locally, but not the case for PR validation in GitHub (if the config change were made in this PR, the GitHub Actions workflow would only lint the changes in this PR, not the full codebase...but personally I still think it's better to update config separately). Last year, the plan was to eventually make PR validation lint the full codebase, but IMO linter config changes are a good reason to keep the limited PR linting indefinitely, in which case we may want to figure out how to update the local make lint
task to more closely match the PR validation behavior.
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.
Sorry, I should have been more clear. It's not linting the entire project, but because we updated all of the SDKv2 Fabric resources/datasources files to use the config.go update change to pass their context in; all of those files are being linted also even though they're not the target of this PR directly.
So to resolve all Fabric linter errors in this project is overkill for this PR. Which is why I've separated out the linter to a different PR while also ensuring the new Streams additions are adherent to it by running make lint
locally.
|
||
func testSweepStreams(region string) error { | ||
var errs []error | ||
log.Printf("[DEBUG] Sweeping Fabric Streams") |
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.
Do we need this logging statement here ? If it's for debugging, should we remove 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.
In test output it will show up and provide useful data for the state of sweepers when run.
|
||
for _, stream := range streams.GetData() { | ||
if sweep.IsSweepableFabricTestResource(stream.GetName()) { | ||
log.Printf("[DEBUG] Deleting stream: %s", stream.GetName()) |
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.
Same here. Do we need this logging statement here ?
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.
Same explanation; In test output it will show up and provide useful data for the state of sweepers when run.
Needs rebase |
…fications
b8a6440
to
f485a2b
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.
LGTM
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #844 +/- ##
==========================================
- Coverage 36.13% 33.96% -2.18%
==========================================
Files 184 187 +3
Lines 24491 24846 +355
==========================================
- Hits 8850 8438 -412
- Misses 15480 16283 +803
+ Partials 161 125 -36 ☔ View full report in Codecov by Sentry. |
…ations in as many files as this change is touching
max-same-issues: 0 |
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 whitespace change in the linter config is tagging DRE for review; if you revert this change then you'll only need review/approval from @d-bhola.
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.
Oh wait, I'm wrong; the changes to config.go
are technically shared, so that requires separate sign-off either way; taking care of that now.
func parseStream(ctx context.Context, stream *fabricv4.Stream, | ||
streamType, name, description, href, uuid, state *basetypes.StringValue, | ||
assetsCount, streamSubscriptionCount *basetypes.Int32Value, | ||
project *fwtypes.ObjectValueOf[ProjectModel], | ||
changeLog *fwtypes.ObjectValueOf[ChangeLogModel]) diag.Diagnostics { |
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 missed this at review time, but this pattern of defining a shared parseThing(...)
function for separate models should not be followed any more. It was a workaround for the fact that terraform-plugin-framework did not support embedded structs when we started adopting it. The framework supports embedded structs now, which means we can reuse the thing.parse(data)
function across different model types for more idiomatic Go code. #853 is an example of that change.
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.
Copy that! Will follow.
This PR is included in version 3.2.0 🎉 |
Using terraform-plugin-framework; added the following:
Included automated testing and docs creation leveraging description on schemas
NOTE: Fixed usage of context within Fabric client creations and updated all usages in SDKv2 as well