From be0358df0294594cdf66c22887f4e3005563ffe9 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 13 Aug 2021 18:31:32 -0400 Subject: [PATCH] acl: remove legacy bootstrap Return an explicit error from the RPC, and remove the flag from the HTTP API. --- agent/acl_endpoint.go | 43 +++++--------------- agent/consul/acl_endpoint_legacy.go | 61 +---------------------------- agent/consul/acl_endpoint_test.go | 36 ----------------- 3 files changed, 12 insertions(+), 128 deletions(-) diff --git a/agent/acl_endpoint.go b/agent/acl_endpoint.go index a0445d8fc..59a51f4de 100644 --- a/agent/acl_endpoint.go +++ b/agent/acl_endpoint.go @@ -4,7 +4,6 @@ import ( "fmt" "io/ioutil" "net/http" - "strconv" "strings" "github.com/hashicorp/consul/acl" @@ -40,40 +39,18 @@ func (s *HTTPHandlers) ACLBootstrap(resp http.ResponseWriter, req *http.Request) args := structs.DCSpecificRequest{ Datacenter: s.agent.config.Datacenter, } - - legacy := false - legacyStr := req.URL.Query().Get("legacy") - if legacyStr != "" { - legacy, _ = strconv.ParseBool(legacyStr) - } - - if legacy && s.agent.delegate.UseLegacyACLs() { - var out structs.ACL - err := s.agent.RPC("ACL.Bootstrap", &args, &out) - if err != nil { - if strings.Contains(err.Error(), structs.ACLBootstrapNotAllowedErr.Error()) { - resp.WriteHeader(http.StatusForbidden) - fmt.Fprint(resp, acl.PermissionDeniedError{Cause: err.Error()}.Error()) - return nil, nil - } else { - return nil, err - } + var out structs.ACLToken + err := s.agent.RPC("ACL.BootstrapTokens", &args, &out) + if err != nil { + if strings.Contains(err.Error(), structs.ACLBootstrapNotAllowedErr.Error()) { + resp.WriteHeader(http.StatusForbidden) + fmt.Fprint(resp, acl.PermissionDeniedError{Cause: err.Error()}.Error()) + return nil, nil + } else { + return nil, err } - return &aclBootstrapResponse{ID: out.ID}, nil - } else { - var out structs.ACLToken - err := s.agent.RPC("ACL.BootstrapTokens", &args, &out) - if err != nil { - if strings.Contains(err.Error(), structs.ACLBootstrapNotAllowedErr.Error()) { - resp.WriteHeader(http.StatusForbidden) - fmt.Fprint(resp, acl.PermissionDeniedError{Cause: err.Error()}.Error()) - return nil, nil - } else { - return nil, err - } - } - return &aclBootstrapResponse{ID: out.SecretID, ACLToken: out}, nil } + return &aclBootstrapResponse{ID: out.SecretID, ACLToken: out}, nil } func (s *HTTPHandlers) ACLReplicationStatus(resp http.ResponseWriter, req *http.Request) (interface{}, error) { diff --git a/agent/consul/acl_endpoint_legacy.go b/agent/consul/acl_endpoint_legacy.go index 5fd0c14df..b7b6f0cca 100644 --- a/agent/consul/acl_endpoint_legacy.go +++ b/agent/consul/acl_endpoint_legacy.go @@ -21,65 +21,8 @@ var ACLEndpointLegacySummaries = []prometheus.SummaryDefinition{ }, } -// Bootstrap is used to perform a one-time ACL bootstrap operation on -// a cluster to get the first management token. -func (a *ACL) Bootstrap(args *structs.DCSpecificRequest, reply *structs.ACL) error { - if done, err := a.srv.ForwardRPC("ACL.Bootstrap", args, reply); done { - return err - } - - // Verify we are allowed to serve this request - if !a.srv.InACLDatacenter() { - return acl.ErrDisabled - } - - if err := a.srv.aclBootstrapAllowed(); err != nil { - return err - } - - // By doing some pre-checks we can head off later bootstrap attempts - // without having to run them through Raft, which should curb abuse. - state := a.srv.fsm.State() - allowed, _, err := state.CanBootstrapACLToken() - if err != nil { - return err - } - if !allowed { - return structs.ACLBootstrapNotAllowedErr - } - - // Propose a new token. - token, err := lib.GenerateUUID(a.srv.checkTokenUUID) - if err != nil { - return fmt.Errorf("failed to make random token: %v", err) - } - - // Attempt a bootstrap. - req := structs.ACLRequest{ - Datacenter: a.srv.config.PrimaryDatacenter, - Op: structs.ACLBootstrapNow, - ACL: structs.ACL{ - ID: token, - Name: "Bootstrap Token", - Type: structs.ACLTokenTypeManagement, - }, - } - resp, err := a.srv.raftApply(structs.ACLRequestType, &req) - if err != nil { - return err - } - switch v := resp.(type) { - case *structs.ACL: - *reply = *v - - default: - // Just log this, since it looks like the bootstrap may have - // completed. - a.logger.Error("Unexpected response during bootstrap", "type", fmt.Sprintf("%T", v)) - } - - a.logger.Info("ACL bootstrap completed") - return nil +func (a *ACL) Bootstrap(*structs.DCSpecificRequest, *structs.ACL) error { + return fmt.Errorf("ACL.Bootstrap: the legacy ACL system has been removed") } // aclApplyInternal is used to apply an ACL request after it has been vetted that diff --git a/agent/consul/acl_endpoint_test.go b/agent/consul/acl_endpoint_test.go index e9848ecac..745e31336 100644 --- a/agent/consul/acl_endpoint_test.go +++ b/agent/consul/acl_endpoint_test.go @@ -25,42 +25,6 @@ import ( "github.com/hashicorp/consul/sdk/testutil/retry" ) -func TestACLEndpoint_Bootstrap(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - _, srv, codec := testACLServerWithConfig(t, func(c *Config) { - c.Build = "0.8.0" // Too low for auto init of bootstrap. - c.PrimaryDatacenter = "dc1" - c.ACLsEnabled = true - // remove the default as we want to bootstrap - c.ACLMasterToken = "" - }, false) - waitForLeaderEstablishment(t, srv) - - // Expect an error initially since ACL bootstrap is not initialized. - arg := structs.DCSpecificRequest{ - Datacenter: "dc1", - } - var out structs.ACL - // We can only do some high - // level checks on the ACL since we don't have control over the UUID or - // Raft indexes at this level. - err := msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", &arg, &out) - require.NoError(t, err) - require.Len(t, out.ID, len("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")) - require.True(t, strings.HasPrefix(out.Name, "Bootstrap Token")) - require.Equal(t, structs.ACLTokenTypeManagement, out.Type) - require.NotEqual(t, uint64(0), out.CreateIndex) - require.NotEqual(t, uint64(0), out.ModifyIndex) - - // Finally, make sure that another attempt is rejected. - err = msgpackrpc.CallWithCodec(codec, "ACL.Bootstrap", &arg, &out) - testutil.RequireErrorContains(t, err, structs.ACLBootstrapNotAllowedErr.Error()) -} - func TestACLEndpoint_BootstrapTokens(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short")