From 46e1275df8b2f4852c35c6701e64e4d330fd1789 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:05:21 -0400 Subject: [PATCH] Move process storage to separate package (#43093) The auth state package contained both process state information and the backing storage used to persist the state. This turns out to be an expensive package for consumers that only care about state and not storage since it brings sqlite into the dependency tree. By splitting storage out to a separate package consumers it makes it possible to build client tools that don't require knowing about process storage to be built without cgo enabled. --- integration/hsm/hsm_test.go | 3 +- integration/instance_test.go | 6 +- lib/auth/init.go | 14 -- lib/auth/state/identity.go | 12 - lib/auth/state/state.go | 173 +------------- lib/auth/storage/storage.go | 215 ++++++++++++++++++ .../state_unix.go => storage/storage_unix.go} | 2 +- .../storage_windows.go} | 2 +- lib/service/service.go | 5 +- tool/tctl/common/admin_action_test.go | 3 +- tool/tctl/common/tctl.go | 3 +- tool/teleport/testenv/test_server.go | 3 +- 12 files changed, 234 insertions(+), 207 deletions(-) create mode 100644 lib/auth/storage/storage.go rename lib/auth/{state/state_unix.go => storage/storage_unix.go} (99%) rename lib/auth/{state/state_windows.go => storage/storage_windows.go} (98%) diff --git a/integration/hsm/hsm_test.go b/integration/hsm/hsm_test.go index 3ce91c7a845b4..f5556ad724595 100644 --- a/integration/hsm/hsm_test.go +++ b/integration/hsm/hsm_test.go @@ -39,6 +39,7 @@ import ( "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/keystore" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/backend/etcdbk" "github.com/gravitational/teleport/lib/backend/lite" @@ -181,7 +182,7 @@ func TestHSMRotation(t *testing.T) { } func getAdminClient(authDataDir string, authAddr string) (*authclient.Client, error) { - identity, err := state.ReadLocalIdentity( + identity, err := storage.ReadLocalIdentity( filepath.Join(authDataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin}) if err != nil { diff --git a/integration/instance_test.go b/integration/instance_test.go index 0c00c6ee4eb4b..baa7f4c79aaa0 100644 --- a/integration/instance_test.go +++ b/integration/instance_test.go @@ -33,7 +33,7 @@ import ( "github.com/gravitational/teleport/api/breaker" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib" - "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/cloud/imds" "github.com/gravitational/teleport/lib/defaults" @@ -141,7 +141,7 @@ func TestInstanceCertReissue(t *testing.T) { authCfg.InstanceMetadataClient = imds.NewDisabledIMDSClient() authRunErrCh := make(chan error, 1) - authIdentitiesCh := make(chan *auth.Identity, 2) + authIdentitiesCh := make(chan *state.Identity, 2) go func() { authRunErrCh <- service.Run(ctx, *authCfg, func(cfg *servicecfg.Config) (service.Process, error) { proc, err := service.NewTeleport(cfg) @@ -198,7 +198,7 @@ func TestInstanceCertReissue(t *testing.T) { agentCfg.InstanceMetadataClient = imds.NewDisabledIMDSClient() agentRunErrCh := make(chan error, 1) - agentIdentitiesCh := make(chan *auth.Identity, 2) + agentIdentitiesCh := make(chan *state.Identity, 2) go func() { agentRunErrCh <- service.Run(ctx, *agentCfg, func(cfg *servicecfg.Config) (service.Process, error) { proc, err := service.NewTeleport(cfg) diff --git a/lib/auth/init.go b/lib/auth/init.go index f11a5384b99f8..779b17bcb08f8 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -1117,20 +1117,6 @@ func checkResourceConsistency(ctx context.Context, keyStore *keystore.Manager, c return nil } -// Identity alias left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -type Identity = state.Identity - -// IdentityID alias left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -type IdentityID = state.IdentityID - -// ReadLocalIdentity left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -func ReadLocalIdentity(dataDir string, id state.IdentityID) (*Identity, error) { - return state.ReadLocalIdentity(dataDir, id) -} - // GenerateIdentity generates identity for the auth server func GenerateIdentity(a *Server, id state.IdentityID, additionalPrincipals, dnsNames []string) (*state.Identity, error) { priv, pub, err := native.GenerateKeyPair() diff --git a/lib/auth/state/identity.go b/lib/auth/state/identity.go index 89cf0f84e8afe..e6b5ceb62adb9 100644 --- a/lib/auth/state/identity.go +++ b/lib/auth/state/identity.go @@ -17,7 +17,6 @@ package state import ( - "context" "crypto/tls" "crypto/x509" "fmt" @@ -338,14 +337,3 @@ func ReadSSHIdentityFromKeyPair(keyBytes, certBytes []byte) (*Identity, error) { Cert: cert, }, nil } - -// ReadLocalIdentity reads, parses and returns the given pub/pri key + cert from the -// key storage (dataDir). -func ReadLocalIdentity(dataDir string, id IdentityID) (*Identity, error) { - storage, err := NewProcessStorage(context.TODO(), dataDir) - if err != nil { - return nil, trace.Wrap(err) - } - defer storage.Close() - return storage.ReadIdentity(IdentityCurrent, id.Role) -} diff --git a/lib/auth/state/state.go b/lib/auth/state/state.go index 8a7807e99af71..aa2f7348d0b52 100644 --- a/lib/auth/state/state.go +++ b/lib/auth/state/state.go @@ -19,53 +19,12 @@ package state import ( - "context" - "encoding/json" - "strings" - "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" - "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/backend" - "github.com/gravitational/teleport/lib/utils" ) -// backend implements abstraction over local or remote storage backend methods -// required for Identity/State storage. -// As in backend.Backend, Item keys are assumed to be valid UTF8, which may be enforced by the -// various Backend implementations. -type stateBackend interface { - // Create creates item if it does not exist - Create(ctx context.Context, i backend.Item) (*backend.Lease, error) - // Put puts value into backend (creates if it does not - // exists, updates it otherwise) - Put(ctx context.Context, i backend.Item) (*backend.Lease, error) - // Get returns a single item or not found error - Get(ctx context.Context, key []byte) (*backend.Item, error) -} - -// ProcessStorage is a backend for local process state, -// it helps to manage rotation for certificate authorities -// and keeps local process credentials - x509 and SSH certs and keys. -type ProcessStorage struct { - // BackendStorage is the SQLite backend used for operations unrelated to storing/reading identities and states. - BackendStorage backend.Backend - - // stateStorage is the backend to store agents' identities and states. - // it is not required to close stateBackend storage because it's either the same as BackendStorage or it is Kubernetes - // which does not require any close method - stateStorage stateBackend -} - -// Close closes all resources used by process storage backend. -func (p *ProcessStorage) Close() error { - // we do not need to close stateBackend storage because it's either the same as backend or it's kubernetes - // which does not require any close method - return p.BackendStorage.Close() -} - const ( // IdentityCurrent is a name for the identity credentials that are // currently used by the process. @@ -75,134 +34,8 @@ const ( IdentityReplacement = "replacement" // stateName is an internal resource object name stateName = "state" - // statesPrefix is a key prefix for object states - statesPrefix = "states" - // idsPrefix is a key prefix for identities - idsPrefix = "ids" ) -// GetState reads rotation state from disk. -func (p *ProcessStorage) GetState(ctx context.Context, role types.SystemRole) (*StateV2, error) { - item, err := p.stateStorage.Get(ctx, backend.Key(statesPrefix, strings.ToLower(role.String()), stateName)) - if err != nil { - return nil, trace.Wrap(err) - } - var res StateV2 - if err := utils.FastUnmarshal(item.Value, &res); err != nil { - return nil, trace.BadParameter(err.Error()) - } - - // an empty InitialLocalVersion is treated as an error by CheckAndSetDefaults, but if the field - // is missing in the underlying storage, that indicates the state was written by an older version of - // teleport that didn't record InitialLocalVersion. In that case, we set a sentinel value to indicate - // that the version is unknown rather than being erroneously omitted. - if res.Spec.InitialLocalVersion == "" { - res.Spec.InitialLocalVersion = unknownLocalVersion - } - - if err := res.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - return &res, nil -} - -// CreateState creates process state if it does not exist yet. -func (p *ProcessStorage) CreateState(role types.SystemRole, state StateV2) error { - if err := state.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(state) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), - Value: value, - } - _, err = p.stateStorage.Create(context.TODO(), item) - if err != nil { - return trace.Wrap(err) - } - return nil -} - -// WriteState writes local cluster state to the backend. -func (p *ProcessStorage) WriteState(role types.SystemRole, state StateV2) error { - if err := state.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(state) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), - Value: value, - } - _, err = p.stateStorage.Put(context.TODO(), item) - if err != nil { - return trace.Wrap(err) - } - return nil -} - -// ReadIdentity reads identity using identity name and role. -func (p *ProcessStorage) ReadIdentity(name string, role types.SystemRole) (*Identity, error) { - if name == "" { - return nil, trace.BadParameter("missing parameter name") - } - item, err := p.stateStorage.Get(context.TODO(), backend.Key(idsPrefix, strings.ToLower(role.String()), name)) - if err != nil { - return nil, trace.Wrap(err) - } - var res IdentityV2 - if err := utils.FastUnmarshal(item.Value, &res); err != nil { - return nil, trace.BadParameter(err.Error()) - } - if err := res.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - return ReadIdentityFromKeyPair(res.Spec.Key, &proto.Certs{ - SSH: res.Spec.SSHCert, - TLS: res.Spec.TLSCert, - TLSCACerts: res.Spec.TLSCACerts, - SSHCACerts: res.Spec.SSHCACerts, - }) -} - -// WriteIdentity writes identity to the backend. -func (p *ProcessStorage) WriteIdentity(name string, id Identity) error { - res := IdentityV2{ - ResourceHeader: types.ResourceHeader{ - Kind: types.KindIdentity, - Version: types.V2, - Metadata: types.Metadata{ - Name: name, - }, - }, - Spec: IdentitySpecV2{ - Key: id.KeyBytes, - SSHCert: id.CertBytes, - TLSCert: id.TLSCertBytes, - TLSCACerts: id.TLSCACertsBytes, - SSHCACerts: id.SSHCACertBytes, - }, - } - if err := res.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(res) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(idsPrefix, strings.ToLower(id.ID.Role.String()), name), - Value: value, - } - _, err = p.stateStorage.Put(context.TODO(), item) - return trace.Wrap(err) -} - // StateV2 is a local process state. type StateV2 struct { // ResourceHeader is a common resource header. @@ -214,7 +47,7 @@ type StateV2 struct { // GetInitialLocalVersion gets the initial local version string. If ok is false it indicates that // this state value was written by a teleport agent that was too old to record the initial local version. func (s *StateV2) GetInitialLocalVersion() (v string, ok bool) { - return s.Spec.InitialLocalVersion, s.Spec.InitialLocalVersion != unknownLocalVersion + return s.Spec.InitialLocalVersion, s.Spec.InitialLocalVersion != UnknownLocalVersion } // CheckAndSetDefaults checks and sets defaults values. @@ -242,10 +75,10 @@ func (s *StateV2) CheckAndSetDefaults() error { return nil } -// unknownVersion is a sentinel value used to distinguish between InitialLocalVersion being missing from +// UnknownVersion is a sentinel value used to distinguish between InitialLocalVersion being missing from // state due to malformed input and InitialLocalVersion being missing due to the state having been created before // teleport started recording InitialLocalVersion. -const unknownLocalVersion = "unknown" +const UnknownLocalVersion = "unknown" // StateSpecV2 is a state spec. type StateSpecV2 struct { diff --git a/lib/auth/storage/storage.go b/lib/auth/storage/storage.go new file mode 100644 index 0000000000000..2930760b66b49 --- /dev/null +++ b/lib/auth/storage/storage.go @@ -0,0 +1,215 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package storage provides a mechanism for interacting with +// the persisted state of a Teleport process. +// +// The state is either persisted locally on disk of the Teleport +// process via sqlite, or if running in Kubernetes, to a Kubernetes +// secret. Callers should take care when importing this package as +// it can cause dependency trees to expand rapidly and also requires +// that cgo is enbaled in order to leverage sqlite. +package storage + +import ( + "context" + "encoding/json" + "strings" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/utils" +) + +const ( + // stateName is an internal resource object name + stateName = "state" + // statesPrefix is a key prefix for object states + statesPrefix = "states" + // idsPrefix is a key prefix for identities + idsPrefix = "ids" +) + +// stateBackend implements abstraction over local or remote storage backend methods +// required for Identity/State storage. +// As in backend.Backend, Item keys are assumed to be valid UTF8, which may be enforced by the +// various Backend implementations. +type stateBackend interface { + // Create creates item if it does not exist + Create(ctx context.Context, i backend.Item) (*backend.Lease, error) + // Put puts value into backend (creates if it does not + // exists, updates it otherwise) + Put(ctx context.Context, i backend.Item) (*backend.Lease, error) + // Get returns a single item or not found error + Get(ctx context.Context, key []byte) (*backend.Item, error) +} + +// ProcessStorage is a backend for local process state, +// it helps to manage rotation for certificate authorities +// and keeps local process credentials - x509 and SSH certs and keys. +type ProcessStorage struct { + // BackendStorage is the SQLite backend used for operations unrelated to storing/reading identities and states. + BackendStorage backend.Backend + + // stateStorage is the backend to store agents' identities and states. + // it is not required to close stateBackend storage because it's either the same as BackendStorage or it is Kubernetes + // which does not require any close method + stateStorage stateBackend +} + +// Close closes all resources used by process storage backend. +func (p *ProcessStorage) Close() error { + // we do not need to close stateBackend storage because it's either the same as backend or it's kubernetes + // which does not require any close method + return p.BackendStorage.Close() +} + +// GetState reads rotation state from disk. +func (p *ProcessStorage) GetState(ctx context.Context, role types.SystemRole) (*state.StateV2, error) { + item, err := p.stateStorage.Get(ctx, backend.Key(statesPrefix, strings.ToLower(role.String()), stateName)) + if err != nil { + return nil, trace.Wrap(err) + } + var res state.StateV2 + if err := utils.FastUnmarshal(item.Value, &res); err != nil { + return nil, trace.BadParameter(err.Error()) + } + + // an empty InitialLocalVersion is treated as an error by CheckAndSetDefaults, but if the field + // is missing in the underlying storage, that indicates the state was written by an older version of + // teleport that didn't record InitialLocalVersion. In that case, we set a sentinel value to indicate + // that the version is unknown rather than being erroneously omitted. + if res.Spec.InitialLocalVersion == "" { + res.Spec.InitialLocalVersion = state.UnknownLocalVersion + } + + if err := res.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + return &res, nil +} + +// CreateState creates process state if it does not exist yet. +func (p *ProcessStorage) CreateState(role types.SystemRole, state state.StateV2) error { + if err := state.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(state) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), + Value: value, + } + _, err = p.stateStorage.Create(context.TODO(), item) + if err != nil { + return trace.Wrap(err) + } + return nil +} + +// WriteState writes local cluster state to the backend. +func (p *ProcessStorage) WriteState(role types.SystemRole, state state.StateV2) error { + if err := state.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(state) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), + Value: value, + } + _, err = p.stateStorage.Put(context.TODO(), item) + if err != nil { + return trace.Wrap(err) + } + return nil +} + +// ReadIdentity reads identity using identity name and role. +func (p *ProcessStorage) ReadIdentity(name string, role types.SystemRole) (*state.Identity, error) { + if name == "" { + return nil, trace.BadParameter("missing parameter name") + } + item, err := p.stateStorage.Get(context.TODO(), backend.Key(idsPrefix, strings.ToLower(role.String()), name)) + if err != nil { + return nil, trace.Wrap(err) + } + var res state.IdentityV2 + if err := utils.FastUnmarshal(item.Value, &res); err != nil { + return nil, trace.BadParameter(err.Error()) + } + if err := res.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + return state.ReadIdentityFromKeyPair(res.Spec.Key, &proto.Certs{ + SSH: res.Spec.SSHCert, + TLS: res.Spec.TLSCert, + TLSCACerts: res.Spec.TLSCACerts, + SSHCACerts: res.Spec.SSHCACerts, + }) +} + +// WriteIdentity writes identity to the backend. +func (p *ProcessStorage) WriteIdentity(name string, id state.Identity) error { + res := state.IdentityV2{ + ResourceHeader: types.ResourceHeader{ + Kind: types.KindIdentity, + Version: types.V2, + Metadata: types.Metadata{ + Name: name, + }, + }, + Spec: state.IdentitySpecV2{ + Key: id.KeyBytes, + SSHCert: id.CertBytes, + TLSCert: id.TLSCertBytes, + TLSCACerts: id.TLSCACertsBytes, + SSHCACerts: id.SSHCACertBytes, + }, + } + if err := res.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(res) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(idsPrefix, strings.ToLower(id.ID.Role.String()), name), + Value: value, + } + _, err = p.stateStorage.Put(context.TODO(), item) + return trace.Wrap(err) +} + +// ReadLocalIdentity reads, parses and returns the given pub/pri key + cert from the +// key storage (dataDir). +func ReadLocalIdentity(dataDir string, id state.IdentityID) (*state.Identity, error) { + storage, err := NewProcessStorage(context.TODO(), dataDir) + if err != nil { + return nil, trace.Wrap(err) + } + defer storage.Close() + return storage.ReadIdentity(state.IdentityCurrent, id.Role) +} diff --git a/lib/auth/state/state_unix.go b/lib/auth/storage/storage_unix.go similarity index 99% rename from lib/auth/state/state_unix.go rename to lib/auth/storage/storage_unix.go index 9ab1379d5b5ee..7bdc6a227b8c0 100644 --- a/lib/auth/state/state_unix.go +++ b/lib/auth/storage/storage_unix.go @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -package state +package storage import ( "context" diff --git a/lib/auth/state/state_windows.go b/lib/auth/storage/storage_windows.go similarity index 98% rename from lib/auth/state/state_windows.go rename to lib/auth/storage/storage_windows.go index a5246017ed1ee..3c262a2802199 100644 --- a/lib/auth/state/state_windows.go +++ b/lib/auth/storage/storage_windows.go @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -package state +package storage import ( "context" diff --git a/lib/service/service.go b/lib/service/service.go index 3ba187cfdb571..20458cd14770a 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -88,6 +88,7 @@ import ( "github.com/gravitational/teleport/lib/auth/keygen" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/automaticupgrades" "github.com/gravitational/teleport/lib/backend" @@ -405,7 +406,7 @@ type TeleportProcess struct { forkedTeleportCount atomic.Int32 // storage is a server local storage - storage *state.ProcessStorage + storage *storage.ProcessStorage // id is a process id - used to identify different processes // during in-process reloads. @@ -917,7 +918,7 @@ func NewTeleport(cfg *servicecfg.Config) (*TeleportProcess, error) { } supervisor := NewSupervisor(processID, cfg.Log) - storage, err := state.NewProcessStorage(supervisor.ExitContext(), filepath.Join(cfg.DataDir, teleport.ComponentProcess)) + storage, err := storage.NewProcessStorage(supervisor.ExitContext(), filepath.Join(cfg.DataDir, teleport.ComponentProcess)) if err != nil { return nil, trace.Wrap(err) } diff --git a/tool/tctl/common/admin_action_test.go b/tool/tctl/common/admin_action_test.go index 52ee2bcc9ad10..48d9bec14bdcc 100644 --- a/tool/tctl/common/admin_action_test.go +++ b/tool/tctl/common/admin_action_test.go @@ -45,6 +45,7 @@ import ( "github.com/gravitational/teleport/lib/auth/mocku2f" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" wancli "github.com/gravitational/teleport/lib/auth/webauthncli" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" libclient "github.com/gravitational/teleport/lib/client" @@ -1065,7 +1066,7 @@ func newAdminActionTestSuite(t *testing.T) *adminActionTestSuite { hostUUID, err := utils.ReadHostUUID(process.Config.DataDir) require.NoError(t, err) - localAdmin, err := state.ReadLocalIdentity( + localAdmin, err := storage.ReadLocalIdentity( filepath.Join(process.Config.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: hostUUID}, ) diff --git a/tool/tctl/common/tctl.go b/tool/tctl/common/tctl.go index 4a4b502915001..24af9c1da1a24 100644 --- a/tool/tctl/common/tctl.go +++ b/tool/tctl/common/tctl.go @@ -42,6 +42,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/client/identityfile" libmfa "github.com/gravitational/teleport/lib/client/mfa" @@ -388,7 +389,7 @@ func ApplyConfig(ccf *GlobalCLIFlags, cfg *servicecfg.Config) (*authclient.Confi } return nil, trace.Wrap(err) } - identity, err := state.ReadLocalIdentity(filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: cfg.HostUUID}) + identity, err := storage.ReadLocalIdentity(filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: cfg.HostUUID}) if err != nil { // The "admin" identity is not present? This means the tctl is running // NOT on the auth server diff --git a/tool/teleport/testenv/test_server.go b/tool/teleport/testenv/test_server.go index 8160937529c15..aa479fa51dd41 100644 --- a/tool/teleport/testenv/test_server.go +++ b/tool/teleport/testenv/test_server.go @@ -49,6 +49,7 @@ import ( "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/cloud/imds" "github.com/gravitational/teleport/lib/defaults" @@ -653,7 +654,7 @@ func MakeDefaultAuthClient(t *testing.T, process *service.TeleportProcess) *auth hostUUID, err := utils.ReadHostUUID(process.Config.DataDir) require.NoError(t, err) - identity, err := state.ReadLocalIdentity( + identity, err := storage.ReadLocalIdentity( filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: hostUUID}, )