diff --git a/globals/prefixes.go b/globals/prefixes.go index 294093e4e..ff70d8bcc 100644 --- a/globals/prefixes.go +++ b/globals/prefixes.go @@ -3,6 +3,8 @@ package globals +import "strings" + // This set of consts is intended to be a place to collect commonly-used // prefixes. This can avoid some cross-package dependency issues. Unlike the // top-level globals package, these are not currently meant to be available to @@ -98,3 +100,34 @@ const ( // WorkerPrefix is the prefix for workers WorkerPrefix = "w" ) + +var topLevelPrefixes = map[string]bool{ + AuthTokenPrefix: true, + PasswordAuthMethodPrefix: true, + OidcAuthMethodPrefix: true, + ProjectPrefix: true, + OrgPrefix: true, + UserPrefix: true, + GroupPrefix: true, + RolePrefix: true, + StaticCredentialStorePrefix: true, + StaticCredentialStorePreviousPrefix: true, + VaultCredentialStorePrefix: true, + StaticHostCatalogPrefix: true, + PluginHostCatalogPrefix: true, + PluginHostCatalogPreviousPrefix: true, + SessionPrefix: true, + TcpTargetPrefix: true, + SshTargetPrefix: true, + WorkerPrefix: true, +} + +// IsTopLevelResourcePrefix takes in a resource ID (or a prefix) and indicates +// via the result whether the ID/prefix corresponds to a top-level resource; +// that is, one (like auth method) that does not have a parent (like account or +// managed group) +func IsTopLevelResourcePrefix(in string) bool { + // If full ID, trim to just prefix + in, _, _ = strings.Cut(in, "_") + return topLevelPrefixes[in] +} diff --git a/globals/prefixes_test.go b/globals/prefixes_test.go new file mode 100644 index 000000000..a3af77895 --- /dev/null +++ b/globals/prefixes_test.go @@ -0,0 +1,25 @@ +package globals + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsTopLevelResourcePrefix(t *testing.T) { + // Test a random sampling + topLevel := []string{VaultCredentialStorePrefix, StaticCredentialStorePrefix, GroupPrefix, TcpTargetPrefix} + child := []string{VaultCredentialLibraryPrefix, OidcManagedGroupPrefix, StaticHostSetPrefix, JsonCredentialPrefix} + + for _, prefix := range topLevel { + assert.True(t, IsTopLevelResourcePrefix(prefix)) + assert.True(t, IsTopLevelResourcePrefix(fmt.Sprintf("%s_foobar", prefix))) + assert.False(t, IsTopLevelResourcePrefix(fmt.Sprintf("%sfoobar", prefix))) + } + for _, prefix := range child { + assert.False(t, IsTopLevelResourcePrefix(prefix)) + assert.False(t, IsTopLevelResourcePrefix(fmt.Sprintf("%s_foobar", prefix))) + assert.False(t, IsTopLevelResourcePrefix(fmt.Sprintf("%sfoobar", prefix))) + } +} diff --git a/internal/types/resource/resource.go b/internal/types/resource/resource.go index f631b92a4..004a80840 100644 --- a/internal/types/resource/resource.go +++ b/internal/types/resource/resource.go @@ -36,6 +36,7 @@ const ( // * The scopes service collection actions for appropriate scopes // * The Test_AnonRestrictions test: update the following line to include the last resource: // for i := resource.Type(1); i <= resource.; i++ { + // * The prefixes and top level prefixes in globals/prefixes.go ) func (r Type) MarshalJSON() ([]byte, error) {