Skip to content

Commit

Permalink
Merge pull request #1240 from gravitational/rjones/clustername-fx
Browse files Browse the repository at this point in the history
Hard fail when trying to update ClusterName.
  • Loading branch information
russjones authored Aug 31, 2017
2 parents 8f4b354 + 64d1fc9 commit 0d1e5f0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 18 deletions.
19 changes: 12 additions & 7 deletions lib/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -493,21 +496,23 @@ 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{
Token: "bar",
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{
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 15 additions & 6 deletions lib/auth/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions lib/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions lib/services/local/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 0d1e5f0

Please sign in to comment.