diff --git a/internal/servers/controller/handlers/targets/target_service.go b/internal/servers/controller/handlers/targets/target_service.go index da31f23f39..db043e18f9 100644 --- a/internal/servers/controller/handlers/targets/target_service.go +++ b/internal/servers/controller/handlers/targets/target_service.go @@ -18,6 +18,7 @@ import ( "github.com/hashicorp/boundary/internal/errors" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/host" + "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/perms" @@ -1709,7 +1710,8 @@ func validateAddSetsRequest(req *pbs.AddTargetHostSetsRequest) error { badFields[globals.HostSetIdsField] = "Must be non-empty." } for _, id := range req.GetHostSetIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSetIdsField] = fmt.Sprintf("Incorrectly formatted host set identifier %q.", id) break } @@ -1729,7 +1731,8 @@ func validateSetSetsRequest(req *pbs.SetTargetHostSetsRequest) error { badFields[globals.VersionField] = "Required field." } for _, id := range req.GetHostSetIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSetIdsField] = fmt.Sprintf("Incorrectly formatted host set identifier %q.", id) break } @@ -1752,7 +1755,8 @@ func validateRemoveSetsRequest(req *pbs.RemoveTargetHostSetsRequest) error { badFields[globals.HostSetIdsField] = "Must be non-empty." } for _, id := range req.GetHostSetIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSetIdsField] = fmt.Sprintf("Incorrectly formatted host set identifier %q.", id) break } @@ -1775,7 +1779,8 @@ func validateAddHostSourcesRequest(req *pbs.AddTargetHostSourcesRequest) error { badFields[globals.HostSourceIdsField] = "Must be non-empty." } for _, id := range req.GetHostSourceIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSourceIdsField] = fmt.Sprintf("Incorrectly formatted host source identifier %q.", id) break } @@ -1795,7 +1800,8 @@ func validateSetHostSourcesRequest(req *pbs.SetTargetHostSourcesRequest) error { badFields[globals.VersionField] = "Required field." } for _, id := range req.GetHostSourceIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSourceIdsField] = fmt.Sprintf("Incorrectly formatted host source identifier %q.", id) break } @@ -1818,7 +1824,8 @@ func validateRemoveHostSourcesRequest(req *pbs.RemoveTargetHostSourcesRequest) e badFields[globals.HostSourceIdsField] = "Must be non-empty." } for _, id := range req.GetHostSourceIds() { - if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) { + if !handlers.ValidId(handlers.Id(id), static.HostSetPrefix) && + !strings.HasPrefix(id, fmt.Sprintf("%s_", plugin.HostSetPrefix)) { badFields[globals.HostSourceIdsField] = fmt.Sprintf("Incorrectly formatted host source identifier %q.", id) break } diff --git a/internal/servers/controller/handlers/targets/target_service_test.go b/internal/servers/controller/handlers/targets/target_service_test.go index 19f9ac908b..b776a69b02 100644 --- a/internal/servers/controller/handlers/targets/target_service_test.go +++ b/internal/servers/controller/handlers/targets/target_service_test.go @@ -18,9 +18,11 @@ import ( "github.com/hashicorp/boundary/internal/db" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" spbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" + "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/plugin/host" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/servers" @@ -979,6 +981,10 @@ func TestAddTargetHostSets(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + addCases := []struct { name string tar *target.TcpTarget @@ -1003,6 +1009,18 @@ func TestAddTargetHostSets(t *testing.T) { addHostSets: []string{hs[1].GetPublicId(), hs[1].GetPublicId()}, resultHostSets: []string{hs[0].GetPublicId(), hs[1].GetPublicId()}, }, + { + name: "Add plugin set on empty target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin empty"), + addHostSets: []string{pluginHs.GetPublicId()}, + resultHostSets: []string{pluginHs.GetPublicId()}, + }, + { + name: "Add plugin set on populated target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin populated", target.WithHostSources([]string{hs[0].GetPublicId()})), + addHostSets: []string{pluginHs.GetPublicId()}, + resultHostSets: []string{hs[0].GetPublicId(), pluginHs.GetPublicId()}, + }, } for _, tc := range addCases { @@ -1095,6 +1113,10 @@ func TestSetTargetHostSets(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + setCases := []struct { name string tar *target.TcpTarget @@ -1125,6 +1147,18 @@ func TestSetTargetHostSets(t *testing.T) { setHostSets: []string{}, resultHostSets: nil, }, + { + name: "Set plugin set on empty target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin empty"), + setHostSets: []string{pluginHs.GetPublicId()}, + resultHostSets: []string{pluginHs.GetPublicId()}, + }, + { + name: "Set plugin set on populated target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin populated", target.WithHostSources([]string{hs[0].GetPublicId()})), + setHostSets: []string{pluginHs.GetPublicId()}, + resultHostSets: []string{pluginHs.GetPublicId()}, + }, } for _, tc := range setCases { t.Run(tc.name, func(t *testing.T) { @@ -1205,6 +1239,10 @@ func TestRemoveTargetHostSets(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + removeCases := []struct { name string tar *target.TcpTarget @@ -1236,6 +1274,12 @@ func TestRemoveTargetHostSets(t *testing.T) { removeHosts: []string{hs[0].GetPublicId(), hs[1].GetPublicId()}, resultHosts: []string{}, }, + { + name: "Remove 1 plugin of 2 sets", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "remove plugin partial", target.WithHostSources([]string{hs[0].GetPublicId(), pluginHs.GetPublicId()})), + removeHosts: []string{pluginHs.GetPublicId()}, + resultHosts: []string{hs[0].GetPublicId()}, + }, } for _, tc := range removeCases { @@ -1333,6 +1377,10 @@ func TestAddTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + addCases := []struct { name string tar *target.TcpTarget @@ -1357,6 +1405,18 @@ func TestAddTargetHostSources(t *testing.T) { addHostSources: []string{hs[1].GetPublicId(), hs[1].GetPublicId()}, resultHostSources: []string{hs[0].GetPublicId(), hs[1].GetPublicId()}, }, + { + name: "Add plugin set on empty target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin empty"), + addHostSources: []string{pluginHs.GetPublicId()}, + resultHostSources: []string{pluginHs.GetPublicId()}, + }, + { + name: "Add plugin set on populated target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin populated", target.WithHostSources([]string{hs[0].GetPublicId()})), + addHostSources: []string{pluginHs.GetPublicId()}, + resultHostSources: []string{hs[0].GetPublicId(), pluginHs.GetPublicId()}, + }, } for _, tc := range addCases { @@ -1449,6 +1509,10 @@ func TestSetTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + setCases := []struct { name string tar *target.TcpTarget @@ -1467,6 +1531,12 @@ func TestSetTargetHostSources(t *testing.T) { setHostSources: []string{hs[1].GetPublicId()}, resultHostSources: []string{hs[1].GetPublicId()}, }, + { + name: "Set plugin set on populated target", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "plugin populated", target.WithHostSources([]string{hs[0].GetPublicId()})), + setHostSources: []string{pluginHs.GetPublicId()}, + resultHostSources: []string{pluginHs.GetPublicId()}, + }, { name: "Set duplicate host set on populated target", tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "duplicate", target.WithHostSources([]string{hs[0].GetPublicId()})), @@ -1559,6 +1629,10 @@ func TestRemoveTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) + plg := host.TestPlugin(t, conn, "test", "test") + pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := plugin.TestSet(t, conn, pluginHc.GetPublicId()) + removeCases := []struct { name string tar *target.TcpTarget @@ -1578,6 +1652,12 @@ func TestRemoveTargetHostSources(t *testing.T) { removeHostSources: []string{hs[1].GetPublicId()}, resultHostSources: []string{hs[0].GetPublicId()}, }, + { + name: "Remove 1 plugin set of 2 sets", + tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "remove plugin partial", target.WithHostSources([]string{hs[0].GetPublicId(), pluginHs.GetPublicId()})), + removeHostSources: []string{pluginHs.GetPublicId()}, + resultHostSources: []string{hs[0].GetPublicId()}, + }, { name: "Remove 1 duplicate set of 2 sets", tar: target.TestTcpTarget(t, conn, proj.GetPublicId(), "remove duplicate", target.WithHostSources([]string{hs[0].GetPublicId(), hs[1].GetPublicId()})),