mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-19 01:58:44 +08:00
Forbid custom namespaces in various resources (#49830)
* Forbid Database and App updates with custom namespaces * Forbid custom namespaces on api/types.KeepAlive * Forbid custom namespaces in api/types.Metadata * Forbid custom namespaces in api/types.RoleV6 * Use a share validation helper, improve error message
This commit is contained in:
@@ -30,7 +30,7 @@ func TestKubeClustersSorter(t *testing.T) {
|
||||
servers := make([]KubeCluster, len(testVals))
|
||||
for i := 0; i < len(testVals); i++ {
|
||||
var err error
|
||||
servers[i], err = NewKubernetesClusterV3FromLegacyCluster("_", &KubernetesCluster{
|
||||
servers[i], err = NewKubernetesClusterV3FromLegacyCluster("", &KubernetesCluster{
|
||||
Name: testVals[i],
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -143,3 +143,17 @@ func IsValidNamespace(s string) bool {
|
||||
}
|
||||
|
||||
var validNamespace = regexp.MustCompile(`^[A-Za-z0-9]+$`)
|
||||
|
||||
// ValidateNamespaceDefault ensures that the namespace is the "default"
|
||||
// namespace.
|
||||
// This is a precursor to a hard-removal of namespaces.
|
||||
func ValidateNamespaceDefault(ns string) error {
|
||||
if ns == defaults.Namespace {
|
||||
return nil
|
||||
}
|
||||
|
||||
const message = "" +
|
||||
"namespace %q invalid, custom namespaces are deprecated; " +
|
||||
"the namespace field should be omitted or set to %q"
|
||||
return trace.BadParameter(message, ns, defaults.Namespace)
|
||||
}
|
||||
|
||||
@@ -67,9 +67,13 @@ func (s *KeepAlive) CheckAndSetDefaults() error {
|
||||
if s.IsEmpty() {
|
||||
return trace.BadParameter("missing resource name")
|
||||
}
|
||||
|
||||
if s.Namespace == "" {
|
||||
s.Namespace = defaults.Namespace
|
||||
}
|
||||
if err := ValidateNamespaceDefault(s.Namespace); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -478,9 +478,13 @@ func (m *Metadata) CheckAndSetDefaults() error {
|
||||
if m.Name == "" {
|
||||
return trace.BadParameter("missing parameter Name")
|
||||
}
|
||||
|
||||
if m.Namespace == "" {
|
||||
m.Namespace = defaults.Namespace
|
||||
}
|
||||
if err := ValidateNamespaceDefault(m.Namespace); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
// adjust expires time to UTC if it's set
|
||||
if m.Expires != nil {
|
||||
|
||||
@@ -266,7 +266,7 @@ func TestMatchSearch_ResourceSpecific(t *testing.T) {
|
||||
name: "kube cluster",
|
||||
matchingSearchVals: []string{"foo", "prod", "env"},
|
||||
newResource: func(t *testing.T) ResourceWithLabels {
|
||||
kc, err := NewKubernetesClusterV3FromLegacyCluster("_", &KubernetesCluster{
|
||||
kc, err := NewKubernetesClusterV3FromLegacyCluster("", &KubernetesCluster{
|
||||
Name: "foo",
|
||||
StaticLabels: labels,
|
||||
})
|
||||
|
||||
+27
-4
@@ -1071,8 +1071,9 @@ func (r *RoleV6) CheckAndSetDefaults() error {
|
||||
if len(r.Spec.Options.BPF) == 0 {
|
||||
r.Spec.Options.BPF = defaults.EnhancedEvents()
|
||||
}
|
||||
if r.Spec.Allow.Namespaces == nil {
|
||||
r.Spec.Allow.Namespaces = []string{defaults.Namespace}
|
||||
if err := checkAndSetRoleConditionNamespaces(&r.Spec.Allow.Namespaces); err != nil {
|
||||
// Using trace.BadParameter instead of trace.Wrap for a better error message.
|
||||
return trace.BadParameter("allow: %s", err)
|
||||
}
|
||||
if r.Spec.Options.RecordSession == nil {
|
||||
r.Spec.Options.RecordSession = &RecordSession{
|
||||
@@ -1175,8 +1176,9 @@ func (r *RoleV6) CheckAndSetDefaults() error {
|
||||
return trace.BadParameter("unrecognized role version: %v", r.Version)
|
||||
}
|
||||
|
||||
if r.Spec.Deny.Namespaces == nil {
|
||||
r.Spec.Deny.Namespaces = []string{defaults.Namespace}
|
||||
if err := checkAndSetRoleConditionNamespaces(&r.Spec.Deny.Namespaces); err != nil {
|
||||
// Using trace.BadParameter instead of trace.Wrap for a better error message.
|
||||
return trace.BadParameter("deny: %s", err)
|
||||
}
|
||||
|
||||
// Validate request.kubernetes_resources fields are all valid.
|
||||
@@ -1322,6 +1324,27 @@ func (r *RoleV6) CheckAndSetDefaults() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkAndSetRoleConditionNamespaces(namespaces *[]string) error {
|
||||
// If nil use the default.
|
||||
// This distinguishes between nil and empty (in accordance to legacy code).
|
||||
if *namespaces == nil {
|
||||
*namespaces = []string{defaults.Namespace}
|
||||
return nil
|
||||
}
|
||||
|
||||
for i, ns := range *namespaces {
|
||||
if ns == Wildcard {
|
||||
continue // OK, wildcard is accepted.
|
||||
}
|
||||
if err := ValidateNamespaceDefault(ns); err != nil {
|
||||
// Using trace.BadParameter instead of trace.Wrap for a better error message.
|
||||
return trace.BadParameter("namespaces[%d]: %s", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns the human readable representation of a role.
|
||||
func (r *RoleV6) String() string {
|
||||
options, _ := json.Marshal(r.Spec.Options)
|
||||
|
||||
@@ -44,6 +44,10 @@ func (s *DatabaseServicesService) UpsertDatabaseService(ctx context.Context, ser
|
||||
if err := services.CheckAndSetDefaults(service); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if err := types.ValidateNamespaceDefault(service.GetNamespace()); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
rev := service.GetRevision()
|
||||
value, err := services.MarshalDatabaseService(service)
|
||||
if err != nil {
|
||||
|
||||
@@ -345,10 +345,10 @@ func (s *PresenceService) UpsertNode(ctx context.Context, server types.Server) (
|
||||
if server.GetNamespace() == "" {
|
||||
server.SetNamespace(apidefaults.Namespace)
|
||||
}
|
||||
|
||||
if n := server.GetNamespace(); n != apidefaults.Namespace {
|
||||
return nil, trace.BadParameter("cannot place node in namespace %q, custom namespaces are deprecated", n)
|
||||
if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
rev := server.GetRevision()
|
||||
value, err := services.MarshalServer(server)
|
||||
if err != nil {
|
||||
@@ -377,10 +377,10 @@ func (s *PresenceService) UpdateNode(ctx context.Context, server types.Server) (
|
||||
if server.GetNamespace() == "" {
|
||||
server.SetNamespace(apidefaults.Namespace)
|
||||
}
|
||||
|
||||
if n := server.GetNamespace(); n != apidefaults.Namespace {
|
||||
return nil, trace.BadParameter("cannot place node in namespace %q, custom namespaces are deprecated", n)
|
||||
if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
rev := server.GetRevision()
|
||||
value, err := services.MarshalServer(server)
|
||||
if err != nil {
|
||||
@@ -1003,6 +1003,10 @@ func (s *PresenceService) UpsertDatabaseServer(ctx context.Context, server types
|
||||
if err := services.CheckAndSetDefaults(server); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
rev := server.GetRevision()
|
||||
value, err := services.MarshalDatabaseServer(server)
|
||||
if err != nil {
|
||||
@@ -1096,6 +1100,10 @@ func (s *PresenceService) UpsertApplicationServer(ctx context.Context, server ty
|
||||
if err := services.CheckAndSetDefaults(server); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if err := types.ValidateNamespaceDefault(server.GetNamespace()); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
rev := server.GetRevision()
|
||||
value, err := services.MarshalAppServer(server)
|
||||
if err != nil {
|
||||
|
||||
@@ -499,7 +499,7 @@ func TestMatchResourceByFilters(t *testing.T) {
|
||||
{
|
||||
name: "kube cluster",
|
||||
resource: func() types.ResourceWithLabels {
|
||||
cluster, err := types.NewKubernetesClusterV3FromLegacyCluster("_", &types.KubernetesCluster{
|
||||
cluster, err := types.NewKubernetesClusterV3FromLegacyCluster("", &types.KubernetesCluster{
|
||||
Name: "foo",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user