Files
teleport/lib/tbot/configtemplate_test.go
T
Tiago Silva 40861809a6 Add RoleV6 resource type (#19324)
This PR includes a new Role resource version that is compatible with V5 spec.

The new resource introduces the `kubernetes_resources` definition that allows operators to limit the Kubernetes resources that each member can access. The `kubernetes_resources` entries must follow the following format: `{"kind":"<kind>", "namespace":"<namespace>","name":"<pod>"}`. Currently, it only supports objects of `kind` `pod`. Valid examples `<namespace>/<name>:
- `*/*`: matches all pods in all namespaces.
- `default/*`: matches all pods in the `default` namespace.
- `*/nginx-*`: matches every pod prefixed with `nginx-` in every namespace.

For older resource versions - V5, V4, V3 - `kubernetes_resources` is automatically populated with `{"kind":"pod","namespace":"*","name":"*"}` to keep compatibility. For the newest version, it's mandatory to define its value otherwise access to pods will be denied.

Part of #18434
2023-01-05 09:58:12 +00:00

126 lines
3.9 KiB
Go

/*
Copyright 2022 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package tbot
import (
"bytes"
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/api/identityfile"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/tbot/bot"
"github.com/gravitational/teleport/lib/tbot/config"
"github.com/gravitational/teleport/lib/tbot/testhelpers"
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
)
// Note: This test lives in main to avoid otherwise inevitable import cycles
// if we tried importing renewal code from the config package.
// validateTemplate loads and validates a config template from the destination
func validateTemplate(t *testing.T, tplI config.Template, dest bot.Destination) {
t.Helper()
// First, make sure all advertised files exist.
for _, file := range tplI.Describe(dest) {
// Don't bother checking directories, they're meant to be black
// boxes. We could implement type-specific checks if we really
// wanted.
if file.IsDir {
continue
}
bytes, err := dest.Read(file.Name)
require.NoError(t, err)
// Should at least be non-empty.
t.Logf("Expected file %q for template %q has length: %d", file.Name, tplI.Name(), len(bytes))
require.Truef(t, len(bytes) > 0, "file %q in template %q must be non-empty", file.Name, tplI.Name())
}
// Next, for supported template types, make sure they're valid.
// TODO: consider adding further type-specific tests.
switch tpl := tplI.(type) {
case *config.TemplateIdentity:
// Make sure the identityfile package can read this identity file.
b, err := dest.Read(tpl.FileName)
require.NoError(t, err)
buf := bytes.NewBuffer(b)
_, err = identityfile.Read(buf)
require.NoError(t, err)
case *config.TemplateTLSCAs:
b, err := dest.Read(tpl.HostCAPath)
require.NoError(t, err)
_, err = tlsca.ParseCertificatePEM(b)
require.NoError(t, err)
b, err = dest.Read(tpl.UserCAPath)
require.NoError(t, err)
_, err = tlsca.ParseCertificatePEM(b)
require.NoError(t, err)
}
}
// TestTemplateRendering performs a full renewal and ensures all expected
// default config templates are present.
func TestDefaultTemplateRendering(t *testing.T) {
t.Parallel()
// Make a new auth server.
log := utils.NewLoggerForTests()
fc, fds := testhelpers.DefaultConfig(t)
_ = testhelpers.MakeAndRunTestAuthServer(t, log, fc, fds)
rootClient := testhelpers.MakeDefaultAuthClient(t, log, fc)
// Make and join a new bot instance.
const roleName = "dummy-role"
role, err := types.NewRole(roleName, types.RoleSpecV6{})
require.NoError(t, err)
require.NoError(t, rootClient.UpsertRole(context.Background(), role))
botParams := testhelpers.MakeBot(t, rootClient, "test", roleName)
botConfig := testhelpers.MakeMemoryBotConfig(t, fc, botParams)
storage, err := botConfig.Storage.GetDestination()
require.NoError(t, err)
b := New(botConfig, log, nil)
ident, err := b.getIdentityFromToken()
require.NoError(t, err)
botClient := testhelpers.MakeBotAuthClient(t, fc, ident)
b._ident = ident
b._client = botClient
err = b.renew(context.Background(), storage)
require.NoError(t, err)
dest := botConfig.Destinations[0]
destImpl, err := dest.GetDestination()
require.NoError(t, err)
for _, templateName := range config.GetRequiredConfigs() {
cfg := dest.GetConfigByName(templateName)
require.NotNilf(t, cfg, "template %q must exist", templateName)
validateTemplate(t, cfg, destImpl)
}
}