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

Return default value for role alias_name_source instead of empty string #134

Closed
wants to merge 2 commits into from

Conversation

tsaarni
Copy link
Contributor

@tsaarni tsaarni commented Feb 3, 2022

Overview

New field alias_name_source was introduced to Role in Vault 1.9.0. If Role was created with older version of Vault, the field is missing from the persisted config in storage. When user sends "Read Role" request to read the stored Role with new Vault version, it will be returned with invalid value "alias_name_source": "". The reason is that the corresponding Go struct gets initialized with empty string when deserializing the stored JSON without the field.

Design of Change

This change returns the default value "serviceaccount_uid" instead of empty string, which makes the returned config data valid (e.g. it can be applied back in "Create Role" request).

Related Issues

Fixes #133

Contributor Checklist

[N/A] Add relevant docs to upstream Vault repository, or sufficient reasoning why docs won’t be added yet
[N/A] Add output for any tests not ran in CI to the PR description (eg, acceptance tests)
[X] Backwards compatible

Field alias_name_source is missing if role was created with Vault prior
version 1.9.0.  When reading stored role back, the go struct entry gets
initialized to "" and user will be presented role with "alias_name_source": ""
in HTTP response, which is invalid value.  This change returns the default
value instead of empty string.

Signed-off-by: Tero Saarni <tero.saarni@est.tech>
@tsaarni
Copy link
Contributor Author

tsaarni commented Feb 3, 2022

Cc @benashz

Copy link
Contributor

@tomhjp tomhjp 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 raising this, LGTM with a couple of optional suggestions.

path_role.go Outdated
Comment on lines 185 to 189
if role.AliasNameSource != "" {
d["alias_name_source"] = role.AliasNameSource
} else {
d["alias_name_source"] = aliasNameSourceDefault
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Very much a nit suggestion, but this is quite a common pattern when dealing with default values IME, so just makes it a tad easier to read.

Suggested change
if role.AliasNameSource != "" {
d["alias_name_source"] = role.AliasNameSource
} else {
d["alias_name_source"] = aliasNameSourceDefault
}
d["alias_name_source"] = aliasNameSourceDefault
if role.AliasNameSource != "" {
d["alias_name_source"] = role.AliasNameSource
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed!

@@ -311,3 +311,70 @@ func TestPath_Delete(t *testing.T) {
t.Fatalf("Unexpected resp data: expected nil got %#v\n", resp.Data)
}
}

func TestPath_Migration(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice test!

t.Fatalf("err:%s resp:%#v\n", err, resp)
}

// Writing the role back should succeed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to tighten the test a little, is it maybe worth deserialising resp.Data into roleStorageEntry as well so that we can assert AliasNameSource is set to the default we would expect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, now fixed!

@tomhjp
Copy link
Contributor

tomhjp commented Feb 4, 2022

I've discussed this internally with the team, and there was some concern about returning data that doesn't match what's in storage. We're planning to open a different PR to make pathRoleCreateUpdate accept an empty string for alias_name_source and treat it as specifying the default value. That way storage will be updated to a valid value, and reads will always reflect the real data. Would that equally solve your issue?

@tsaarni
Copy link
Contributor Author

tsaarni commented Feb 4, 2022

Yes, that would solve it as well

@tomhjp
Copy link
Contributor

tomhjp commented Feb 4, 2022

OK great, sorry for the late change of tack.

@tomhjp tomhjp closed this Feb 4, 2022
@tsaarni
Copy link
Contributor Author

tsaarni commented Feb 4, 2022

@tomhjp One question though:

One alternative that I was pondering about while writing #133 was not to return alias_name_source in "Read Role" at all. That applied to this PR #134 would have been following additional change:

diff --git a/path_role.go b/path_role.go
index ea64e69..2f6ed7d 100644
--- a/path_role.go
+++ b/path_role.go
@@ -182,7 +182,6 @@ func (b *kubeAuthBackend) pathRoleRead(ctx context.Context, req *logical.Request
        if role.NumUses > 0 {
                d["num_uses"] = role.NumUses
        }
-       d["alias_name_source"] = aliasNameSourceDefault
        if role.AliasNameSource != "" {
                d["alias_name_source"] = role.AliasNameSource
        }

In that case empty string would not necessarily need to be accepted, and the public documentation would not necessarily need to change. So in a way, maybe impacts are less but it still would fix my problem of reading and re-applying the config.

But for me any approach is completely ok :)

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

Successfully merging this pull request may close these issues.

Re-configuring role fails after upgrading existing deployment to Vault 1.9.x
2 participants