diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index 90f798f7f736b..ed83e1911e837 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -475,14 +475,17 @@ func (s *AuthSuite) TestUpdateConfig(c *C) { Authority: authority.New(), } authServer := NewAuthServer(authConfig) - // set cluster name + + // try and set cluster name, this should fail because you can only set the + // cluster name once clusterName, err := services.NewClusterName(services.ClusterNameSpecV2{ ClusterName: "foo.localhost", }) c.Assert(err, IsNil) err = authServer.SetClusterName(clusterName) - c.Assert(err, IsNil) - // set static tokens + c.Assert(err, NotNil) + // try and set static tokens, this should be successfull because the last + // one to upsert tokens wins staticTokens, err := services.NewStaticTokens(services.StaticTokensSpecV2{ StaticTokens: []services.ProvisionToken{services.ProvisionToken{ Token: "bar", @@ -493,10 +496,11 @@ func (s *AuthSuite) TestUpdateConfig(c *C) { err = authServer.SetStaticTokens(staticTokens) c.Assert(err, IsNil) - // check first auth server and make sure it returns the new values + // check first auth server and make sure it returns the correct values + // (original cluster name, new static tokens) cn, err = s.a.GetClusterName() c.Assert(err, IsNil) - c.Assert(cn.GetClusterName(), Equals, "foo.localhost") + c.Assert(cn.GetClusterName(), Equals, "me.localhost") st, err = s.a.GetStaticTokens() c.Assert(err, IsNil) c.Assert(st.GetStaticTokens(), DeepEquals, []services.ProvisionToken{services.ProvisionToken{ @@ -504,10 +508,11 @@ func (s *AuthSuite) TestUpdateConfig(c *C) { Roles: teleport.Roles{teleport.Role("baz")}, }}) - // check second auth server and make sure it also has the new values + // check second auth server and make sure it also has the correct values + // (original cluster name, new static tokens) cn, err = authServer.GetClusterName() c.Assert(err, IsNil) - c.Assert(cn.GetClusterName(), Equals, "foo.localhost") + c.Assert(cn.GetClusterName(), Equals, "me.localhost") st, err = authServer.GetStaticTokens() c.Assert(err, IsNil) c.Assert(st.GetStaticTokens(), DeepEquals, []services.ProvisionToken{services.ProvisionToken{ diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 5937b661eec71..67f699b07e0b1 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -783,7 +783,7 @@ func (a *AuthWithRoles) GetClusterName() (services.ClusterName, error) { return a.authServer.GetClusterName() } -// SetClusterName sets the name of the cluster. +// SetClusterName sets the name of the cluster. SetClusterName can only be called once. func (a *AuthWithRoles) SetClusterName(c services.ClusterName) error { if err := a.action(defaults.Namespace, services.KindClusterName, services.VerbCreate); err != nil { return trace.Wrap(err) diff --git a/lib/auth/init.go b/lib/auth/init.go index f998b6505d731..7160d3fe7c359 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -155,25 +155,34 @@ func Init(cfg InitConfig, dynamicConfig bool) (*AuthServer, *Identity, error) { log.Infof("[INIT] Created Reverse Tunnel: %v", tunnel) } - // always upload cluster configuration when auth service starts. the last - // one always wins. + // cluster name can only be set once. if it has already been set and we are + // trying to update it to something else, hard fail. err = asrv.SetClusterName(cfg.ClusterName) - if err != nil { + if err != nil && !trace.IsAlreadyExists(err) { return nil, nil, trace.Wrap(err) } - log.Infof("[INIT] Updating Cluster Configuration: ClusterName: %v", cfg.ClusterName) + if trace.IsAlreadyExists(err) { + cn, err := asrv.GetClusterName() + if err != nil { + return nil, nil, trace.Wrap(err) + } + if cn.GetClusterName() != cfg.ClusterName.GetClusterName() { + return nil, nil, trace.BadParameter("cannot rename cluster %q to %q: clusters cannot be renamed", cn.GetClusterName(), cfg.ClusterName.GetClusterName()) + } + } + log.Debugf("[INIT] Cluster Configuration: %v", cfg.ClusterName) err = asrv.SetStaticTokens(cfg.StaticTokens) if err != nil { return nil, nil, trace.Wrap(err) } - log.Infof("[INIT] Updating Cluster Configuration: Static Tokens: %v", cfg.StaticTokens) + log.Infof("[INIT] Updating Cluster Configuration: %v", cfg.StaticTokens) err = asrv.SetAuthPreference(cfg.AuthPreference) if err != nil { return nil, nil, trace.Wrap(err) } - log.Infof("[INIT] Updating Cluster Configuration: AuthPreference: %v", cfg.AuthPreference) + log.Infof("[INIT] Updating Cluster Configuration: %v", cfg.AuthPreference) // always create the default namespace err = asrv.UpsertNamespace(services.NewNamespace(defaults.Namespace)) diff --git a/lib/service/service.go b/lib/service/service.go index 90e4026ea3bef..203d3cf573187 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -226,10 +226,10 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.AuthServers = []utils.NetAddr{cfg.Auth.SSHAddr} } - // if user did not provide auth domain name, use this host UUID + // if user did not provide auth domain name, use this host's name if cfg.Auth.Enabled && cfg.Auth.ClusterName == nil { cfg.Auth.ClusterName, err = services.NewClusterName(services.ClusterNameSpecV2{ - ClusterName: cfg.HostUUID, + ClusterName: cfg.Hostname, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/services/local/configuration.go b/lib/services/local/configuration.go index c804c21a5423a..6143b8ca81f77 100644 --- a/lib/services/local/configuration.go +++ b/lib/services/local/configuration.go @@ -47,14 +47,15 @@ func (s *ClusterConfigurationService) GetClusterName() (services.ClusterName, er return services.GetClusterNameMarshaler().Unmarshal(data) } -// SetClusterName sets the name of the cluster in the backend. +// SetClusterName sets the name of the cluster in the backend. SetClusterName +// can only be called once on a cluster after which it will return trace.AlreadyExists. func (s *ClusterConfigurationService) SetClusterName(c services.ClusterName) error { data, err := services.GetClusterNameMarshaler().Marshal(c) if err != nil { return trace.Wrap(err) } - err = s.UpsertVal([]string{"cluster_configuration"}, "name", []byte(data), backend.Forever) + err = s.CreateVal([]string{"cluster_configuration"}, "name", []byte(data), backend.Forever) if err != nil { return trace.Wrap(err) }