Skip to content
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

Fixing issues with workspace_key_prefix for s3 backend #16932

Merged
merged 5 commits into from Jan 5, 2018
Merged

Fixing issues with workspace_key_prefix for s3 backend #16932

merged 5 commits into from Jan 5, 2018

Conversation

ghost
Copy link

@ghost ghost commented Dec 15, 2017

I believe this will fix #16383 and #16387

@ghost
Copy link
Author

ghost commented Dec 16, 2017

@jbardin @apparentlymart
Ran into this bug today and I think I've got a fix here. I added some tests for this functionality and cleaned up a bit. However, I haven't manually tested this. I'm hoping this could be released in a minor version.

Copy link
Member

@jbardin jbardin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting the PR @rv-jmaggio. The implementation shown here will fail the full backend test set, so there's a few issues that need to be sorted out.

@@ -51,6 +58,12 @@ func (b *Backend) keyEnv(key string) string {
return ""
}

parts = strings.Split(parts[1], "/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the key names are allowed to have / characters, you're going to want SplitN with 3 here.

t.Fatal(err)
}

if err := testGetWorkspaceForKey(b1, "root/userA/ws1/tfstate", "ws1"); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the prefix is root/userA and the key is ws1/tfstate, ws1 can't be the workspace name.

t.Fatal(err)
}

if err := testGetWorkspaceForKey(b1, "root/userA/ws2/tfstate", "ws2"); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above for this check and the one below. The tests are checking the output of getWorkspaceForKey, but that doesn't match how it's used by the backend.


if err := testGetWorkspaceForKey(b2, "root/userA/ws2/env1/tfstate", "ws2"); err != nil {
t.Fatal(err)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once of the new backend configs needs to be run through the TestBackend helper, which would have failed with either b1 or b2.

@ghost
Copy link
Author

ghost commented Dec 18, 2017

@jbardin I updated from your feedback. I did some testing in a playground and you are definitely correct on SplitN. Evidently I was a bit confused when I wrote my test cases, so I made them a bit more clear. I think this should be good to go now. I am happy to contribute to a tool I use nearly every day 😃

Copy link
Member

@jbardin jbardin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget these are all run as acceptance tests, so you need to set TF_ACC=1!

func getWorkspaceForKey(key string, b *Backend) string {
if b.workspaceKeyPrefix == "" {
parts := strings.Split(key, "/")
if len(parts) > 1 && parts[1] == key {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what the intent here was, but you can't split key, then still have parts[1] == key. It's also going to fail for the same reason as before, since we need to be able to support / in the key for compatibility.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes the intention was to check b.keyName, not key. Thanks

}

func testGetWorkspaceForKey(b *Backend, key string, expected string) error {
if getWorkspaceForKey(key, b) != expected {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should record the computed value, so the error can show both the expected value and what you received.

@@ -249,6 +249,63 @@ func TestBackendExtraPaths(t *testing.T) {
}
}

func TestKeyEnv(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though the rest of the ACC tests pass again, this test still fails.

if err := testGetWorkspaceForKey(b2, "env:/ws3/tfstate", "ws3"); err != nil {
t.Fatal(err)
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not creating this bucket for the backend tests, though it currently fails earlier.

func TestKeyEnv(t *testing.T) {
testACC(t)
bucketName := fmt.Sprintf("terraform-remote-s3-test-%x", time.Now().Unix())
keyName := "tfstate"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test cases are good, but let's go back to having a keyName with a / to make sure it's still supported after we introduce them into the prefix.

@ghost
Copy link
Author

ghost commented Dec 19, 2017

@jbardin
Ah, thanks for the pointer on TF_ACC=1.

So I made those changes, but I was getting an error when running backend.TestBackend(t, b0, nil)
--- FAIL: TestKeyEnv (23.36s) backend_test.go:339: creating S3 bucket terraform-remote-s3-test-5a39211b-0 in us-west-2 backend_test.go:339: creating S3 bucket terraform-remote-s3-test-5a39211e-1 in us-west-2 backend_test.go:339: creating S3 bucket terraform-remote-s3-test-5a392121-2 in us-west-2 backend_test.go:308: bad: []string{"default"} FAIL

It seems like when workspace_key_prefix is set to "" then the workspace folder default isn't being created? Not exactly sure what to make of this.

@ghost
Copy link
Author

ghost commented Dec 19, 2017

Ah actually it seems to be related to the implementation for empty string workspace_key_prefix. I think I can get that fixed.

edit: Maybe not, after making some adjustments it is still failing with the same error

@ghost
Copy link
Author

ghost commented Dec 19, 2017

I think there may be an issue with this implementation for a workspace_key_prefix set to ""

https://github.com/hashicorp/terraform/blob/master/backend/remote-state/s3/backend_state.go#L180

@ghost
Copy link
Author

ghost commented Dec 20, 2017

@jbardin I had to make 2 more changes to the backend_state implementation to allow for empty string prefix. I ran the acceptance tests (actually in acceptance test mode) and they all passed.

@jbardin
Copy link
Member

jbardin commented Dec 21, 2017

Hi @rv-jmaggio,

Thanks for the update!
This is looking good. I'll do a final review after we return from the break and aim to get this into the next release.

Copy link
Member

@jbardin jbardin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 Thanks for putting in the extra work to get this in!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

workspace_key_prefix contains more than one folder
2 participants