Skip to content

Commit

Permalink
Define specific kind for request modes kube resources field
Browse files Browse the repository at this point in the history
  • Loading branch information
kimlisa committed Oct 4, 2024
1 parent cc9b45c commit ae41067
Show file tree
Hide file tree
Showing 6 changed files with 2,243 additions and 2,107 deletions.
14 changes: 12 additions & 2 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2666,8 +2666,19 @@ message AccessCapabilitiesRequest {
bool FilterRequestableRolesByResource = 6 [(gogoproto.jsontag) = "filter_requestable_roles_by_resource,omitempty"];
}

// RequestModeKubernetesResources is the Kubernetes resource identifier used
// in access request mode settings.
// Modeled after existing message KubernetesResource.
message RequestModeKubernetesResource {
// Kind specifies the Kubernetes Resource type.
string Kind = 1 [(gogoproto.jsontag) = "kind,omitempty"];
}

// AccessRequestMode describes request mode settings for applicable resources.
message AccessRequestMode {
repeated KubernetesResource KubernetesResources = 1 [
// KubernetesResources defines which Kubernetes subresources a user can
// request during request creation.
repeated RequestModeKubernetesResource KubernetesResources = 1 [
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "kubernetes_resources,omitempty"
];
Expand Down Expand Up @@ -3309,7 +3320,6 @@ message DatabasePermission {
// KubernetesResource is the Kubernetes resource identifier.
message KubernetesResource {
// Kind specifies the Kubernetes Resource type.
// At the moment only "pod" is supported.
string Kind = 1 [(gogoproto.jsontag) = "kind,omitempty"];
// Namespace is the resource namespace.
// It supports wildcards.
Expand Down
24 changes: 3 additions & 21 deletions api/types/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -1757,8 +1757,6 @@ func setDefaultKubernetesVerbs(spec *RoleSpecV6) {
// - Kind belongs to KubernetesResourcesKinds
// - Name is not empty
// - Namespace is not empty
//
// Keep in sync with related func validateKubeResourcesForAccessRequestMode
func validateKubeResources(roleVersion string, kubeResources []KubernetesResource) error {
for _, kubeResource := range kubeResources {
if !slices.Contains(KubernetesResourcesKinds, kubeResource.Kind) && kubeResource.Kind != Wildcard {
Expand Down Expand Up @@ -1799,26 +1797,10 @@ func validateKubeResources(roleVersion string, kubeResources []KubernetesResourc
}

// validateKubeResourcesForAccessRequestMode validates each kubeResources entry for `options.request_mode.kubernetes_resources` field.
// Currently the only supported field for this particular field is:
// - Kind (belonging to KubernetesResourcesKinds)
//
// All other fields (eg: Name) might get future support.
//
// Keep in sync with related func validateKubeResources
func validateKubeResourcesForAccessRequestMode(roleVersion string, kubeResources []KubernetesResource) error {
func validateKubeResourcesForAccessRequestMode(roleVersion string, kubeResources []RequestModeKubernetesResource) error {
for _, kubeResource := range kubeResources {
if !slices.Contains(KubernetesResourcesKinds, kubeResource.Kind) && kubeResource.Kind != Wildcard {
return trace.BadParameter("request_mode kubernetes_resource kind %q is invalid or unsupported; Supported: %v", kubeResource.Kind, append([]string{Wildcard}, KubernetesResourcesKinds...))
}

if kubeResource.Name != "" {
return trace.BadParameter("request_mode kubernetes_resources field %q is not supported", "name")
}
if kubeResource.Namespace != "" {
return trace.BadParameter("request_mode kubernetes_resources field %q is not supported", "namespace")
}
if len(kubeResource.Verbs) > 0 {
return trace.BadParameter("request_mode kubernetes_resources field %q is not supported", "verbs")
return trace.BadParameter("request_mode.kubernetes_resource kind %q is invalid or unsupported; Supported: %v", kubeResource.Kind, append([]string{Wildcard}, KubernetesResourcesKinds...))
}

// Only Pod resources are supported in role version <=V6.
Expand All @@ -1828,7 +1810,7 @@ func validateKubeResourcesForAccessRequestMode(roleVersion string, kubeResources
// Teleport does not support role versions < v3.
case V6, V5, V4, V3:
if kubeResource.Kind != KindKubePod {
return trace.BadParameter("request_mode kubernetes_resources kind %q is not supported in role version %q. Upgrade the role version to %q", kubeResource.Kind, roleVersion, V7)
return trace.BadParameter("request_mode.kubernetes_resources kind %q is not supported in role version %q. Upgrade the role version to %q", kubeResource.Kind, roleVersion, V7)
}
}
}
Expand Down
71 changes: 16 additions & 55 deletions api/types/role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,26 +351,26 @@ func TestRole_GetKubeResources(t *testing.T) {
func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
type args struct {
version string
resources []KubernetesResource
resources []RequestModeKubernetesResource
}
tests := []struct {
name string
args args
want []KubernetesResource
want []RequestModeKubernetesResource
assertErrorCreation require.ErrorAssertionFunc
}{
{
name: "valid single value",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: KindKubePod,
},
},
},
assertErrorCreation: require.NoError,
want: []KubernetesResource{
want: []RequestModeKubernetesResource{
{
Kind: KindKubePod,
},
Expand All @@ -387,14 +387,14 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "valid wildcard value",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
},
},
assertErrorCreation: require.NoError,
want: []KubernetesResource{
want: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand All @@ -404,7 +404,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "valid multi values",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: KindKubeNamespace,
},
Expand All @@ -417,7 +417,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
},
},
assertErrorCreation: require.NoError,
want: []KubernetesResource{
want: []RequestModeKubernetesResource{
{
Kind: KindKubeNamespace,
},
Expand All @@ -433,7 +433,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "valid multi values with wildcard",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: KindKubeNamespace,
},
Expand All @@ -443,7 +443,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
},
},
assertErrorCreation: require.NoError,
want: []KubernetesResource{
want: []RequestModeKubernetesResource{
{
Kind: KindKubeNamespace,
},
Expand All @@ -456,7 +456,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "invalid single value",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: KindKubernetesCluster,
},
Expand All @@ -468,7 +468,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "invalid multi value",
args: args{
version: V7,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand All @@ -482,50 +482,11 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
},
assertErrorCreation: require.Error,
},
{
name: "invalid unsupported field `name`",
args: args{
version: V7,
resources: []KubernetesResource{
{
Kind: Wildcard,
Name: "unsupported",
},
},
},
assertErrorCreation: require.Error,
},
{
name: "invalid unsupported field `namespace`",
args: args{
version: V7,
resources: []KubernetesResource{
{
Kind: Wildcard,
Namespace: "unsupported",
},
},
},
assertErrorCreation: require.Error,
},
{
name: "invalid unsupported field `verbs`",
args: args{
version: V7,
resources: []KubernetesResource{
{
Kind: Wildcard,
Verbs: []string{"unsupported"},
},
},
},
assertErrorCreation: require.Error,
},
{
name: "invalid kinds not supported for v6",
args: args{
version: V6,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand All @@ -537,7 +498,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "invalid kinds not supported for v5",
args: args{
version: V6,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand All @@ -549,7 +510,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "invalid kinds not supported for v4",
args: args{
version: V6,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand All @@ -561,7 +522,7 @@ func TestRole_OptionsRequestModeKubeResources(t *testing.T) {
name: "invalid kinds not supported for v3",
args: args{
version: V6,
resources: []KubernetesResource{
resources: []RequestModeKubernetesResource{
{
Kind: Wildcard,
},
Expand Down
Loading

0 comments on commit ae41067

Please sign in to comment.