From 96ec059025312a7a65421c2d5266f8ab01e21f3a Mon Sep 17 00:00:00 2001 From: freddygv Date: Thu, 18 Jun 2020 17:15:42 -0600 Subject: [PATCH] Revert "ACL Node Identities (#7970)" This reverts commit d3881dd754ebf27c2aed5153750489d7793d596e. --- agent/consul/acl.go | 55 +---------- agent/consul/acl_authmethod.go | 37 +++---- agent/consul/acl_endpoint.go | 53 +--------- agent/consul/intention_endpoint_test.go | 27 ++++-- agent/consul/leader.go | 1 - agent/consul/leader_test.go | 4 +- agent/consul/server_test.go | 10 +- agent/consul/state/acl.go | 20 +--- agent/structs/acl.go | 97 ------------------- agent/structs/acl_legacy.go | 1 - agent/structs/acl_oss.go | 42 -------- api/acl.go | 10 -- command/acl/acl_helpers.go | 17 ---- command/acl/role/create/role_create.go | 15 +-- command/acl/role/create/role_create_test.go | 75 +++++++------- command/acl/role/formatter.go | 13 --- .../testdata/FormatRole/basic.json.golden | 8 -- .../FormatRole/basic.pretty-meta.golden | 6 -- .../testdata/FormatRole/basic.pretty.golden | 3 - .../testdata/FormatRole/complex.json.golden | 33 ------- .../FormatRole/complex.pretty-meta.golden | 14 --- .../testdata/FormatRole/complex.pretty.golden | 11 --- .../testdata/FormatRoleList/basic.json.golden | 10 -- .../FormatRoleList/basic.pretty-meta.golden | 6 -- .../FormatRoleList/basic.pretty.golden | 3 - .../FormatRoleList/complex.json.golden | 35 ------- .../FormatRoleList/complex.pretty-meta.golden | 14 --- .../FormatRoleList/complex.pretty.golden | 11 --- command/acl/role/update/role_update.go | 25 ----- command/acl/role/update/role_update_test.go | 74 +++++++------- command/acl/token/create/token_create.go | 15 +-- command/acl/token/create/token_create_test.go | 90 ++++++++--------- command/acl/token/formatter.go | 16 --- .../testdata/FormatToken/basic.json.golden | 10 -- .../FormatToken/basic.pretty-meta.golden | 8 -- .../testdata/FormatToken/basic.pretty.golden | 5 - .../testdata/FormatToken/complex.json.golden | 47 --------- .../FormatToken/complex.pretty-meta.golden | 21 ---- .../FormatToken/complex.pretty.golden | 18 ---- .../testdata/FormatToken/legacy.json.golden | 10 -- .../FormatToken/legacy.pretty-meta.golden | 10 -- .../testdata/FormatToken/legacy.pretty.golden | 7 -- .../FormatTokenList/basic.json.golden | 12 --- .../FormatTokenList/basic.pretty-meta.golden | 8 -- .../FormatTokenList/basic.pretty.golden | 5 - .../FormatTokenList/complex.json.golden | 49 ---------- .../complex.pretty-meta.golden | 21 ---- .../FormatTokenList/complex.pretty.golden | 18 ---- .../FormatTokenList/legacy.json.golden | 12 --- .../FormatTokenList/legacy.pretty-meta.golden | 8 -- .../FormatTokenList/legacy.pretty.golden | 5 - command/acl/token/update/token_update.go | 31 ------ website/pages/api-docs/acl/binding-rules.mdx | 23 ----- website/pages/api-docs/acl/roles.mdx | 58 ----------- website/pages/api-docs/acl/tokens.mdx | 24 ----- website/pages/docs/acl/acl-system.mdx | 39 -------- 56 files changed, 165 insertions(+), 1135 deletions(-) delete mode 100644 command/acl/role/testdata/FormatRole/basic.json.golden delete mode 100644 command/acl/role/testdata/FormatRole/basic.pretty-meta.golden delete mode 100644 command/acl/role/testdata/FormatRole/basic.pretty.golden delete mode 100644 command/acl/role/testdata/FormatRole/complex.json.golden delete mode 100644 command/acl/role/testdata/FormatRole/complex.pretty-meta.golden delete mode 100644 command/acl/role/testdata/FormatRole/complex.pretty.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/basic.json.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/basic.pretty-meta.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/basic.pretty.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/complex.json.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden delete mode 100644 command/acl/role/testdata/FormatRoleList/complex.pretty.golden delete mode 100644 command/acl/token/testdata/FormatToken/basic.json.golden delete mode 100644 command/acl/token/testdata/FormatToken/basic.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatToken/basic.pretty.golden delete mode 100644 command/acl/token/testdata/FormatToken/complex.json.golden delete mode 100644 command/acl/token/testdata/FormatToken/complex.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatToken/complex.pretty.golden delete mode 100644 command/acl/token/testdata/FormatToken/legacy.json.golden delete mode 100644 command/acl/token/testdata/FormatToken/legacy.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatToken/legacy.pretty.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/basic.json.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/basic.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/basic.pretty.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/complex.json.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/complex.pretty.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/legacy.json.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/legacy.pretty-meta.golden delete mode 100644 command/acl/token/testdata/FormatTokenList/legacy.pretty.golden diff --git a/agent/consul/acl.go b/agent/consul/acl.go index 81730a67a4c4..cb22dba47438 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -99,10 +99,6 @@ func (id *missingIdentity) ServiceIdentityList() []*structs.ACLServiceIdentity { return nil } -func (id *missingIdentity) NodeIdentityList() []*structs.ACLNodeIdentity { - return nil -} - func (id *missingIdentity) IsExpired(asOf time.Time) bool { return false } @@ -652,9 +648,8 @@ func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) ( policyIDs := identity.PolicyIDs() roleIDs := identity.RoleIDs() serviceIdentities := identity.ServiceIdentityList() - nodeIdentities := identity.NodeIdentityList() - if len(policyIDs) == 0 && len(serviceIdentities) == 0 && len(roleIDs) == 0 && len(nodeIdentities) == 0 { + if len(policyIDs) == 0 && len(serviceIdentities) == 0 && len(roleIDs) == 0 { policy := identity.EmbeddedPolicy() if policy != nil { return []*structs.ACLPolicy{policy}, nil @@ -676,17 +671,14 @@ func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) ( policyIDs = append(policyIDs, link.ID) } serviceIdentities = append(serviceIdentities, role.ServiceIdentities...) - nodeIdentities = append(nodeIdentities, role.NodeIdentityList()...) } // Now deduplicate any policies or service identities that occur more than once. policyIDs = dedupeStringSlice(policyIDs) serviceIdentities = dedupeServiceIdentities(serviceIdentities) - nodeIdentities = dedupeNodeIdentities(nodeIdentities) // Generate synthetic policies for all service identities in effect. syntheticPolicies := r.synthesizePoliciesForServiceIdentities(serviceIdentities, identity.EnterpriseMetadata()) - syntheticPolicies = append(syntheticPolicies, r.synthesizePoliciesForNodeIdentities(nodeIdentities)...) // For the new ACLs policy replication is mandatory for correct operation on servers. Therefore // we only attempt to resolve policies locally @@ -713,19 +705,6 @@ func (r *ACLResolver) synthesizePoliciesForServiceIdentities(serviceIdentities [ return syntheticPolicies } -func (r *ACLResolver) synthesizePoliciesForNodeIdentities(nodeIdentities []*structs.ACLNodeIdentity) []*structs.ACLPolicy { - if len(nodeIdentities) == 0 { - return nil - } - - syntheticPolicies := make([]*structs.ACLPolicy, 0, len(nodeIdentities)) - for _, n := range nodeIdentities { - syntheticPolicies = append(syntheticPolicies, n.SyntheticPolicy()) - } - - return syntheticPolicies -} - func dedupeServiceIdentities(in []*structs.ACLServiceIdentity) []*structs.ACLServiceIdentity { // From: https://github.com/golang/go/wiki/SliceTricks#in-place-deduplicate-comparable @@ -760,38 +739,6 @@ func dedupeServiceIdentities(in []*structs.ACLServiceIdentity) []*structs.ACLSer return in[:j+1] } -func dedupeNodeIdentities(in []*structs.ACLNodeIdentity) []*structs.ACLNodeIdentity { - // From: https://github.com/golang/go/wiki/SliceTricks#in-place-deduplicate-comparable - - if len(in) <= 1 { - return in - } - - sort.Slice(in, func(i, j int) bool { - if in[i].NodeName < in[j].NodeName { - return true - } - - return in[i].Datacenter < in[j].Datacenter - }) - - j := 0 - for i := 1; i < len(in); i++ { - if in[j].NodeName == in[i].NodeName && in[j].Datacenter == in[i].Datacenter { - continue - } - j++ - in[j] = in[i] - } - - // Discard the skipped items. - for i := j + 1; i < len(in); i++ { - in[i] = nil - } - - return in[:j+1] -} - func mergeStringSlice(a, b []string) []string { out := make([]string, 0, len(a)+len(b)) out = append(out, a...) diff --git a/agent/consul/acl_authmethod.go b/agent/consul/acl_authmethod.go index 2e973c6a128d..bcdedfc5d523 100644 --- a/agent/consul/acl_authmethod.go +++ b/agent/consul/acl_authmethod.go @@ -36,12 +36,6 @@ func (s *Server) loadAuthMethodValidator(idx uint64, method *structs.ACLAuthMeth return v, nil } -type aclBindings struct { - roles []structs.ACLTokenRoleLink - serviceIdentities []*structs.ACLServiceIdentity - nodeIdentities []*structs.ACLNodeIdentity -} - // evaluateRoleBindings evaluates all current binding rules associated with the // given auth method against the verified data returned from the authentication // process. @@ -52,13 +46,13 @@ func (s *Server) evaluateRoleBindings( verifiedIdentity *authmethod.Identity, methodMeta *structs.EnterpriseMeta, targetMeta *structs.EnterpriseMeta, -) (*aclBindings, error) { +) ([]*structs.ACLServiceIdentity, []structs.ACLTokenRoleLink, error) { // Only fetch rules that are relevant for this method. _, rules, err := s.fsm.State().ACLBindingRuleList(nil, validator.Name(), methodMeta) if err != nil { - return nil, err + return nil, nil, err } else if len(rules) == 0 { - return nil, nil + return nil, nil, nil } // Find all binding rules that match the provided fields. @@ -69,39 +63,36 @@ func (s *Server) evaluateRoleBindings( } } if len(matchingRules) == 0 { - return nil, nil + return nil, nil, nil } // For all matching rules compute the attributes of a token. - var bindings aclBindings + var ( + roleLinks []structs.ACLTokenRoleLink + serviceIdentities []*structs.ACLServiceIdentity + ) for _, rule := range matchingRules { bindName, valid, err := computeBindingRuleBindName(rule.BindType, rule.BindName, verifiedIdentity.ProjectedVars) if err != nil { - return nil, fmt.Errorf("cannot compute %q bind name for bind target: %v", rule.BindType, err) + return nil, nil, fmt.Errorf("cannot compute %q bind name for bind target: %v", rule.BindType, err) } else if !valid { - return nil, fmt.Errorf("computed %q bind name for bind target is invalid: %q", rule.BindType, bindName) + return nil, nil, fmt.Errorf("computed %q bind name for bind target is invalid: %q", rule.BindType, bindName) } switch rule.BindType { case structs.BindingRuleBindTypeService: - bindings.serviceIdentities = append(bindings.serviceIdentities, &structs.ACLServiceIdentity{ + serviceIdentities = append(serviceIdentities, &structs.ACLServiceIdentity{ ServiceName: bindName, }) - case structs.BindingRuleBindTypeNode: - bindings.nodeIdentities = append(bindings.nodeIdentities, &structs.ACLNodeIdentity{ - NodeName: bindName, - Datacenter: s.config.Datacenter, - }) - case structs.BindingRuleBindTypeRole: _, role, err := s.fsm.State().ACLRoleGetByName(nil, bindName, targetMeta) if err != nil { - return nil, err + return nil, nil, err } if role != nil { - bindings.roles = append(bindings.roles, structs.ACLTokenRoleLink{ + roleLinks = append(roleLinks, structs.ACLTokenRoleLink{ ID: role.ID, }) } @@ -111,7 +102,7 @@ func (s *Server) evaluateRoleBindings( } } - return &bindings, nil + return serviceIdentities, roleLinks, nil } // doesSelectorMatch checks that a single selector matches the provided vars. diff --git a/agent/consul/acl_endpoint.go b/agent/consul/acl_endpoint.go index f4d29ab9f732..1a18dbe790fc 100644 --- a/agent/consul/acl_endpoint.go +++ b/agent/consul/acl_endpoint.go @@ -35,8 +35,6 @@ var ( validPolicyName = regexp.MustCompile(`^[A-Za-z0-9\-_]{1,128}$`) validServiceIdentityName = regexp.MustCompile(`^[a-z0-9]([a-z0-9\-_]*[a-z0-9])?$`) serviceIdentityNameMaxLength = 256 - validNodeIdentityName = regexp.MustCompile(`^[a-z0-9]([a-z0-9\-_]*[a-z0-9])?$`) - nodeIdentityNameMaxLength = 256 validRoleName = regexp.MustCompile(`^[A-Za-z0-9\-_]{1,256}$`) validAuthMethod = regexp.MustCompile(`^[A-Za-z0-9\-_]{1,128}$`) ) @@ -322,7 +320,6 @@ func (a *ACL) TokenClone(args *structs.ACLTokenSetRequest, reply *structs.ACLTok Policies: token.Policies, Roles: token.Roles, ServiceIdentities: token.ServiceIdentities, - NodeIdentities: token.NodeIdentities, Local: token.Local, Description: token.Description, ExpirationTime: token.ExpirationTime, @@ -619,19 +616,6 @@ func (a *ACL) tokenSetInternal(args *structs.ACLTokenSetRequest, reply *structs. } token.ServiceIdentities = dedupeServiceIdentities(token.ServiceIdentities) - for _, nodeid := range token.NodeIdentities { - if nodeid.NodeName == "" { - return fmt.Errorf("Node identity is missing the node name field on this token") - } - if nodeid.Datacenter == "" { - return fmt.Errorf("Node identity is missing the datacenter field on this token") - } - if !isValidNodeIdentityName(nodeid.NodeName) { - return fmt.Errorf("Node identity has an invalid name. Only alphanumeric characters, '-' and '_' are allowed") - } - } - token.NodeIdentities = dedupeNodeIdentities(token.NodeIdentities) - if token.Rules != "" { return fmt.Errorf("Rules cannot be specified for this token") } @@ -717,8 +701,7 @@ func computeBindingRuleBindName(bindType, bindName string, projectedVars map[str switch bindType { case structs.BindingRuleBindTypeService: valid = isValidServiceIdentityName(bindName) - case structs.BindingRuleBindTypeNode: - valid = isValidNodeIdentityName(bindName) + case structs.BindingRuleBindTypeRole: valid = validRoleName.MatchString(bindName) @@ -740,17 +723,6 @@ func isValidServiceIdentityName(name string) bool { return validServiceIdentityName.MatchString(name) } -// isValidNodeIdentityName returns true if the provided name can be used as -// an ACLNodeIdentity NodeName. This is more restrictive than standard -// catalog registration, which basically takes the view that "everything is -// valid". -func isValidNodeIdentityName(name string) bool { - if len(name) < 1 || len(name) > nodeIdentityNameMaxLength { - return false - } - return validNodeIdentityName.MatchString(name) -} - func (a *ACL) TokenDelete(args *structs.ACLTokenDeleteRequest, reply *string) error { if err := a.aclPreCheck(); err != nil { return err @@ -1601,19 +1573,6 @@ func (a *ACL) RoleSet(args *structs.ACLRoleSetRequest, reply *structs.ACLRole) e } role.ServiceIdentities = dedupeServiceIdentities(role.ServiceIdentities) - for _, nodeid := range role.NodeIdentities { - if nodeid.NodeName == "" { - return fmt.Errorf("Node identity is missing the node name field on this role") - } - if nodeid.Datacenter == "" { - return fmt.Errorf("Node identity is missing the datacenter field on this role") - } - if !isValidNodeIdentityName(nodeid.NodeName) { - return fmt.Errorf("Node identity has an invalid name. Only alphanumeric characters, '-' and '_' are allowed") - } - } - role.NodeIdentities = dedupeNodeIdentities(role.NodeIdentities) - // calculate the hash for this role role.SetHash(true) @@ -1934,7 +1893,6 @@ func (a *ACL) BindingRuleSet(args *structs.ACLBindingRuleSetRequest, reply *stru switch rule.BindType { case structs.BindingRuleBindTypeService: - case structs.BindingRuleBindTypeNode: case structs.BindingRuleBindTypeRole: default: return fmt.Errorf("Invalid Binding Rule: unknown BindType %q", rule.BindType) @@ -2408,14 +2366,14 @@ func (a *ACL) tokenSetFromAuthMethod( } // 3. send map through role bindings - bindings, err := a.srv.evaluateRoleBindings(validator, verifiedIdentity, entMeta, targetMeta) + serviceIdentities, roleLinks, err := a.srv.evaluateRoleBindings(validator, verifiedIdentity, entMeta, targetMeta) if err != nil { return err } // We try to prevent the creation of a useless token without taking a trip // through the state store if we can. - if bindings == nil || (len(bindings.serviceIdentities) == 0 && len(bindings.nodeIdentities) == 0 && len(bindings.roles) == 0) { + if len(serviceIdentities) == 0 && len(roleLinks) == 0 { return acl.ErrPermissionDenied } @@ -2435,9 +2393,8 @@ func (a *ACL) tokenSetFromAuthMethod( Description: description, Local: true, AuthMethod: method.Name, - ServiceIdentities: bindings.serviceIdentities, - NodeIdentities: bindings.nodeIdentities, - Roles: bindings.roles, + ServiceIdentities: serviceIdentities, + Roles: roleLinks, ExpirationTTL: method.MaxTokenTTL, EnterpriseMeta: *targetMeta, } diff --git a/agent/consul/intention_endpoint_test.go b/agent/consul/intention_endpoint_test.go index 6359aa4824d9..d469bd3913da 100644 --- a/agent/consul/intention_endpoint_test.go +++ b/agent/consul/intention_endpoint_test.go @@ -392,8 +392,13 @@ service "foo" { func TestIntention_WildcardACLEnforcement(t *testing.T) { t.Parallel() - _, srv, codec := testACLServerWithConfig(t, nil, false) - waitForLeaderEstablishment(t, srv) + dir, srv := testACLServerWithConfig(t, nil, false) + defer os.RemoveAll(dir) + defer srv.Shutdown() + codec := rpcClient(t, srv) + defer codec.Close() + + testrpc.WaitForLeader(t, srv.RPC, "dc1") // create some test policies. @@ -1217,8 +1222,13 @@ func TestIntentionMatch_good(t *testing.T) { func TestIntentionMatch_acl(t *testing.T) { t.Parallel() - _, srv, codec := testACLServerWithConfig(t, nil, false) - waitForLeaderEstablishment(t, srv) + dir1, s1 := testACLServerWithConfig(t, nil, false) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + codec := rpcClient(t, s1) + defer codec.Close() + + testrpc.WaitForLeader(t, s1.RPC, "dc1") token, err := upsertTestTokenWithPolicyRules(codec, TestDefaultMasterToken, "dc1", `service "bar" { policy = "write" }`) require.NoError(t, err) @@ -1454,8 +1464,13 @@ service "bar" { func TestIntentionCheck_match(t *testing.T) { t.Parallel() - _, srv, codec := testACLServerWithConfig(t, nil, false) - waitForLeaderEstablishment(t, srv) + dir1, s1 := testACLServerWithConfig(t, nil, false) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + codec := rpcClient(t, s1) + defer codec.Close() + + testrpc.WaitForLeader(t, s1.RPC, "dc1") token, err := upsertTestTokenWithPolicyRules(codec, TestDefaultMasterToken, "dc1", `service "api" { policy = "read" }`) require.NoError(t, err) diff --git a/agent/consul/leader.go b/agent/consul/leader.go index bd95260acc80..67a7c7ab49b3 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -731,7 +731,6 @@ func (s *Server) legacyACLTokenUpgrade(ctx context.Context) error { // Assign the global-management policy to legacy management tokens if len(newToken.Policies) == 0 && len(newToken.ServiceIdentities) == 0 && - len(newToken.NodeIdentities) == 0 && len(newToken.Roles) == 0 && newToken.Type == structs.ACLTokenTypeManagement { newToken.Policies = append(newToken.Policies, structs.ACLTokenPolicyLink{ID: structs.ACLPolicyGlobalManagementID}) diff --git a/agent/consul/leader_test.go b/agent/consul/leader_test.go index 508509868dca..9a2f628c4b7f 100644 --- a/agent/consul/leader_test.go +++ b/agent/consul/leader_test.go @@ -1314,7 +1314,9 @@ func TestLeader_ACLLegacyReplication(t *testing.T) { c.Datacenter = "dc2" c.ACLTokenReplication = true } - _, srv, _ := testACLServerWithConfig(t, cb, true) + dir, srv := testACLServerWithConfig(t, cb, true) + defer os.RemoveAll(dir) + defer srv.Shutdown() waitForLeaderEstablishment(t, srv) require.True(t, srv.leaderRoutineManager.IsRunning(legacyACLReplicationRoutineName)) diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index 8822a98c9b1b..b0cc16337204 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -8,7 +8,6 @@ import ( "crypto/x509" "fmt" "net" - "net/rpc" "os" "strings" "sync/atomic" @@ -280,19 +279,14 @@ func testServerWithConfig(t *testing.T, cb func(*Config)) (string, *Server) { } // cb is a function that can alter the test servers configuration prior to the server starting. -func testACLServerWithConfig(t *testing.T, cb func(*Config), initReplicationToken bool) (string, *Server, rpc.ClientCodec) { +func testACLServerWithConfig(t *testing.T, cb func(*Config), initReplicationToken bool) (string, *Server) { dir, srv := testServerWithConfig(t, testServerACLConfig(cb)) - t.Cleanup(func() { os.RemoveAll(dir) }) - t.Cleanup(func() { srv.Shutdown() }) if initReplicationToken { // setup some tokens here so we get less warnings in the logs srv.tokens.UpdateReplicationToken(TestDefaultMasterToken, token.TokenSourceConfig) } - - codec := rpcClient(t, srv) - t.Cleanup(func() { codec.Close() }) - return dir, srv, codec + return dir, srv } func newServer(c *Config) (*Server, error) { diff --git a/agent/consul/state/acl.go b/agent/consul/state/acl.go index c1b6e6aa0f7e..2ef35e67d047 100644 --- a/agent/consul/state/acl.go +++ b/agent/consul/state/acl.go @@ -739,17 +739,8 @@ func (s *Store) aclTokenSetTxn(tx *txn, idx uint64, token *structs.ACLToken, cas } } - for _, nodeid := range token.NodeIdentities { - if nodeid.NodeName == "" { - return fmt.Errorf("Encountered a Token with an empty node identity name in the state store") - } - if nodeid.Datacenter == "" { - return fmt.Errorf("Encountered a Token with an empty node identity datacenter in the state store") - } - } - if prohibitUnprivileged { - if numValidRoles == 0 && numValidPolicies == 0 && len(token.ServiceIdentities) == 0 && len(token.NodeIdentities) == 0 { + if numValidRoles == 0 && numValidPolicies == 0 && len(token.ServiceIdentities) == 0 { return ErrTokenHasNoPrivileges } } @@ -1367,15 +1358,6 @@ func (s *Store) aclRoleSetTxn(tx *txn, idx uint64, role *structs.ACLRole, allowM } } - for _, nodeid := range role.NodeIdentities { - if nodeid.NodeName == "" { - return fmt.Errorf("Encountered a Role with an empty node identity name in the state store") - } - if nodeid.Datacenter == "" { - return fmt.Errorf("Encountered a Role with an empty node identity datacenter in the state store") - } - } - if err := s.aclRoleUpsertValidateEnterprise(tx, role, existing); err != nil { return err } diff --git a/agent/structs/acl.go b/agent/structs/acl.go index de01c6e2f7c2..0045bef72df8 100644 --- a/agent/structs/acl.go +++ b/agent/structs/acl.go @@ -119,7 +119,6 @@ type ACLIdentity interface { RoleIDs() []string EmbeddedPolicy() *ACLPolicy ServiceIdentityList() []*ACLServiceIdentity - NodeIdentityList() []*ACLNodeIdentity IsExpired(asOf time.Time) bool IsLocal() bool EnterpriseMetadata() *EnterpriseMeta @@ -190,50 +189,6 @@ func (s *ACLServiceIdentity) SyntheticPolicy(entMeta *EnterpriseMeta) *ACLPolicy return policy } -// ACLNodeIdentity represents a high-level grant of all privileges -// necessary to assume the identity of that node and manage it. -type ACLNodeIdentity struct { - // NodeName identities the Node that this identity authorizes access to - NodeName string - - // Datacenter is required and specifies the datacenter of the node. - Datacenter string -} - -func (s *ACLNodeIdentity) Clone() *ACLNodeIdentity { - s2 := *s - return &s2 -} - -func (s *ACLNodeIdentity) AddToHash(h hash.Hash) { - h.Write([]byte(s.NodeName)) - h.Write([]byte(s.Datacenter)) -} - -func (s *ACLNodeIdentity) EstimateSize() int { - return len(s.NodeName) + len(s.Datacenter) -} - -func (s *ACLNodeIdentity) SyntheticPolicy() *ACLPolicy { - // Given that we validate this string name before persisting, we do not - // have to escape it before doing the following interpolation. - rules := fmt.Sprintf(aclPolicyTemplateNodeIdentity, s.NodeName) - - hasher := fnv.New128a() - hashID := fmt.Sprintf("%x", hasher.Sum([]byte(rules))) - - policy := &ACLPolicy{} - policy.ID = hashID - policy.Name = fmt.Sprintf("synthetic-policy-%s", hashID) - policy.Description = "synthetic policy" - policy.Rules = rules - policy.Syntax = acl.SyntaxCurrent - policy.Datacenters = []string{s.Datacenter} - policy.EnterpriseMeta = *DefaultEnterpriseMeta() - policy.SetHash(true) - return policy -} - type ACLToken struct { // This is the UUID used for tracking and management purposes AccessorID string @@ -257,9 +212,6 @@ type ACLToken struct { // List of services to generate synthetic policies for. ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - // The node identities that this token should be allowed to manage. - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` - // Type is the V1 Token Type // DEPRECATED (ACL-Legacy-Compat) - remove once we no longer support v1 ACL compat // Even though we are going to auto upgrade management tokens we still @@ -350,7 +302,6 @@ func (t *ACLToken) Clone() *ACLToken { t2.Policies = nil t2.Roles = nil t2.ServiceIdentities = nil - t2.NodeIdentities = nil if len(t.Policies) > 0 { t2.Policies = make([]ACLTokenPolicyLink, len(t.Policies)) @@ -366,13 +317,6 @@ func (t *ACLToken) Clone() *ACLToken { t2.ServiceIdentities[i] = s.Clone() } } - if len(t.NodeIdentities) > 0 { - t2.NodeIdentities = make([]*ACLNodeIdentity, len(t.NodeIdentities)) - for i, n := range t.NodeIdentities { - t2.NodeIdentities[i] = n.Clone() - } - } - return &t2 } @@ -438,7 +382,6 @@ func (t *ACLToken) HasExpirationTime() bool { func (t *ACLToken) UsesNonLegacyFields() bool { return len(t.Policies) > 0 || len(t.ServiceIdentities) > 0 || - len(t.NodeIdentities) > 0 || len(t.Roles) > 0 || t.Type == "" || t.HasExpirationTime() || @@ -519,10 +462,6 @@ func (t *ACLToken) SetHash(force bool) []byte { srvid.AddToHash(hash) } - for _, nodeID := range t.NodeIdentities { - nodeID.AddToHash(hash) - } - t.EnterpriseMeta.addToHash(hash, false) // Finalize the hash @@ -546,9 +485,6 @@ func (t *ACLToken) EstimateSize() int { for _, srvid := range t.ServiceIdentities { size += srvid.EstimateSize() } - for _, nodeID := range t.NodeIdentities { - size += nodeID.EstimateSize() - } return size + t.EnterpriseMeta.estimateSize() } @@ -561,7 +497,6 @@ type ACLTokenListStub struct { Policies []ACLTokenPolicyLink `json:",omitempty"` Roles []ACLTokenRoleLink `json:",omitempty"` ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` Local bool AuthMethod string `json:",omitempty"` ExpirationTime *time.Time `json:",omitempty"` @@ -582,7 +517,6 @@ func (token *ACLToken) Stub() *ACLTokenListStub { Policies: token.Policies, Roles: token.Roles, ServiceIdentities: token.ServiceIdentities, - NodeIdentities: token.NodeIdentities, Local: token.Local, AuthMethod: token.AuthMethod, ExpirationTime: token.ExpirationTime, @@ -877,9 +811,6 @@ type ACLRole struct { // List of services to generate synthetic policies for. ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - // List of nodes to generate synthetic policies for. - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` - // Hash of the contents of the role // This does not take into account the ID (which is immutable) // nor the raft metadata. @@ -918,7 +849,6 @@ func (r *ACLRole) Clone() *ACLRole { r2 := *r r2.Policies = nil r2.ServiceIdentities = nil - r2.NodeIdentities = nil if len(r.Policies) > 0 { r2.Policies = make([]ACLRolePolicyLink, len(r.Policies)) @@ -930,12 +860,6 @@ func (r *ACLRole) Clone() *ACLRole { r2.ServiceIdentities[i] = s.Clone() } } - if len(r.NodeIdentities) > 0 { - r2.NodeIdentities = make([]*ACLNodeIdentity, len(r.NodeIdentities)) - for i, n := range r.NodeIdentities { - r2.NodeIdentities[i] = n.Clone() - } - } return &r2 } @@ -964,9 +888,6 @@ func (r *ACLRole) SetHash(force bool) []byte { for _, srvid := range r.ServiceIdentities { srvid.AddToHash(hash) } - for _, nodeID := range r.NodeIdentities { - nodeID.AddToHash(hash) - } r.EnterpriseMeta.addToHash(hash, false) @@ -991,9 +912,6 @@ func (r *ACLRole) EstimateSize() int { for _, srvid := range r.ServiceIdentities { size += srvid.EstimateSize() } - for _, nodeID := range r.NodeIdentities { - size += nodeID.EstimateSize() - } return size + r.EnterpriseMeta.estimateSize() } @@ -1027,21 +945,6 @@ const ( // // If it does not exist at login-time the rule is ignored. BindingRuleBindTypeRole = "role" - - // BindingRuleBindTypeNode is the binding rule bind type that assigns - // a Node Identity to the token that is created using the value of - // the computed BindName as the NodeName like: - // - // &ACLToken{ - // ...other fields... - // NodeIdentities: []*ACLNodeIdentity{ - // &ACLNodeIdentity{ - // NodeName: "", - // Datacenter: "" - // } - // } - // } - BindingRuleBindTypeNode = "node" ) type ACLBindingRule struct { diff --git a/agent/structs/acl_legacy.go b/agent/structs/acl_legacy.go index b7b466a1d596..6e3ac351a1d7 100644 --- a/agent/structs/acl_legacy.go +++ b/agent/structs/acl_legacy.go @@ -78,7 +78,6 @@ func (a *ACL) Convert() *ACLToken { Description: a.Name, Policies: nil, ServiceIdentities: nil, - NodeIdentities: nil, Type: a.Type, Rules: a.Rules, Local: false, diff --git a/agent/structs/acl_oss.go b/agent/structs/acl_oss.go index 0a43ee0b4634..43c11c691bd9 100644 --- a/agent/structs/acl_oss.go +++ b/agent/structs/acl_oss.go @@ -26,24 +26,6 @@ service_prefix "" { node_prefix "" { policy = "read" }` - - // A typical Consul node requires two permissions for itself. - // node:write - // - register itself in the catalog - // - update its network coordinates - // - potentially used to delete services during anti-entropy - // service:read - // - used during anti-entropy to discover all services that - // are registered to the node. That way the node can diff - // its local state against an accurate depiction of the - // remote state. - aclPolicyTemplateNodeIdentity = ` -node "%[1]s" { - policy = "write" -} -service_prefix "" { - policy = "read" -}` ) type ACLAuthMethodEnterpriseFields struct{} @@ -69,27 +51,3 @@ func (p *ACLPolicy) EnterprisePolicyMeta() *acl.EnterprisePolicyMeta { func (m *ACLAuthMethod) TargetEnterpriseMeta(_ *EnterpriseMeta) *EnterpriseMeta { return &m.EnterpriseMeta } - -func (t *ACLToken) NodeIdentityList() []*ACLNodeIdentity { - if len(t.NodeIdentities) == 0 { - return nil - } - - out := make([]*ACLNodeIdentity, 0, len(t.NodeIdentities)) - for _, n := range t.NodeIdentities { - out = append(out, n.Clone()) - } - return out -} - -func (r *ACLRole) NodeIdentityList() []*ACLNodeIdentity { - if len(r.NodeIdentities) == 0 { - return nil - } - - out := make([]*ACLNodeIdentity, 0, len(r.NodeIdentities)) - for _, n := range r.NodeIdentities { - out = append(out, n.Clone()) - } - return out -} diff --git a/api/acl.go b/api/acl.go index aa4411b24401..618a49d6b474 100644 --- a/api/acl.go +++ b/api/acl.go @@ -37,7 +37,6 @@ type ACLToken struct { Policies []*ACLTokenPolicyLink `json:",omitempty"` Roles []*ACLTokenRoleLink `json:",omitempty"` ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` Local bool AuthMethod string `json:",omitempty"` ExpirationTTL time.Duration `json:",omitempty"` @@ -62,7 +61,6 @@ type ACLTokenListEntry struct { Policies []*ACLTokenPolicyLink `json:",omitempty"` Roles []*ACLTokenRoleLink `json:",omitempty"` ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` Local bool AuthMethod string `json:",omitempty"` ExpirationTime *time.Time `json:",omitempty"` @@ -107,13 +105,6 @@ type ACLServiceIdentity struct { Datacenters []string `json:",omitempty"` } -// ACLNodeIdentity represents a high-level grant of all necessary privileges -// to assume the identity of the named Node in the Catalog and within Connect. -type ACLNodeIdentity struct { - NodeName string - Datacenter string -} - // ACLPolicy represents an ACL Policy. type ACLPolicy struct { ID string @@ -153,7 +144,6 @@ type ACLRole struct { Description string Policies []*ACLRolePolicyLink `json:",omitempty"` ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` Hash []byte CreateIndex uint64 ModifyIndex uint64 diff --git a/command/acl/acl_helpers.go b/command/acl/acl_helpers.go index 296a6b9f905b..590a22b3bbd3 100644 --- a/command/acl/acl_helpers.go +++ b/command/acl/acl_helpers.go @@ -217,23 +217,6 @@ func ExtractServiceIdentities(serviceIdents []string) ([]*api.ACLServiceIdentity return out, nil } -func ExtractNodeIdentities(nodeIdents []string) ([]*api.ACLNodeIdentity, error) { - var out []*api.ACLNodeIdentity - for _, nodeidRaw := range nodeIdents { - parts := strings.Split(nodeidRaw, ":") - switch len(parts) { - case 2: - out = append(out, &api.ACLNodeIdentity{ - NodeName: parts[0], - Datacenter: parts[1], - }) - default: - return nil, fmt.Errorf("Malformed -node-identity argument: %q", nodeidRaw) - } - } - return out, nil -} - // TestKubernetesJWT_A is a valid service account jwt extracted from a minikube setup. // // { diff --git a/command/acl/role/create/role_create.go b/command/acl/role/create/role_create.go index c86848986e4d..aae712a46c9d 100644 --- a/command/acl/role/create/role_create.go +++ b/command/acl/role/create/role_create.go @@ -29,7 +29,6 @@ type cmd struct { policyIDs []string policyNames []string serviceIdents []string - nodeIdents []string showMeta bool format string @@ -48,9 +47,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.serviceIdents), "service-identity", "Name of a "+ "service identity to use for this role. May be specified multiple times. Format is "+ "the SERVICENAME or SERVICENAME:DATACENTER1,DATACENTER2,...") - c.flags.Var((*flags.AppendSliceValue)(&c.nodeIdents), "node-identity", "Name of a "+ - "node identity to use for this role. May be specified multiple times. Format is "+ - "NODENAME:DATACENTER") c.flags.StringVar( &c.format, "format", @@ -75,8 +71,8 @@ func (c *cmd) Run(args []string) int { return 1 } - if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 { - c.UI.Error(fmt.Sprintf("Cannot create a role without specifying -policy-name, -policy-id, -service-identity, or -node-identity at least once")) + if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.serviceIdents) == 0 { + c.UI.Error(fmt.Sprintf("Cannot create a role without specifying -policy-name, -policy-id, or -service-identity at least once")) return 1 } @@ -113,13 +109,6 @@ func (c *cmd) Run(args []string) int { } newRole.ServiceIdentities = parsedServiceIdents - parsedNodeIdents, err := acl.ExtractNodeIdentities(c.nodeIdents) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - newRole.NodeIdentities = parsedNodeIdents - r, _, err := client.ACL().RoleCreate(newRole, nil) if err != nil { c.UI.Error(fmt.Sprintf("Failed to create new role: %v", err)) diff --git a/command/acl/role/create/role_create_test.go b/command/acl/role/create/role_create_test.go index b3c03a662ac7..13053b872d87 100644 --- a/command/acl/role/create/role_create_test.go +++ b/command/acl/role/create/role_create_test.go @@ -41,18 +41,8 @@ func TestRoleCreateCommand_Pretty(t *testing.T) { defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") - run := func(t *testing.T, args []string) *api.ACLRole { - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(append(args, "-format=json", "-http-addr="+a.HTTPAddr())) - require.Equal(t, 0, code) - require.Empty(t, ui.ErrorWriter.String()) - - var role api.ACLRole - require.NoError(t, json.Unmarshal(ui.OutputWriter.Bytes(), &role)) - return &role - } + ui := cli.NewMockUi() + cmd := New(ui) // Create a policy client := a.Client() @@ -64,55 +54,64 @@ func TestRoleCreateCommand_Pretty(t *testing.T) { require.NoError(t, err) // create with policy by name - t.Run("policy-name", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-token=root", "-name=role-with-policy-by-name", "-description=test-role", "-policy-name=" + policy.Name, - }) - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0) + require.Empty(t, ui.ErrorWriter.String()) + } // create with policy by id - t.Run("policy-id", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-token=root", "-name=role-with-policy-by-id", "-description=test-role", "-policy-id=" + policy.ID, - }) - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0) + require.Empty(t, ui.ErrorWriter.String()) + } // create with service identity - t.Run("service-identity", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-token=root", "-name=role-with-service-identity", "-description=test-role", "-service-identity=web", - }) - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0) + require.Empty(t, ui.ErrorWriter.String()) + } // create with service identity scoped to 2 DCs - t.Run("dc-scoped-service-identity", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-token=root", "-name=role-with-service-identity-in-2-dcs", "-description=test-role", "-service-identity=db:abc,xyz", - }) - }) - - t.Run("node-identity", func(t *testing.T) { - role := run(t, []string{ - "-token=root", - "-name=role-with-node-identity", - "-description=test-role", - "-node-identity=foo:bar", - }) + } - require.Len(t, role.NodeIdentities, 1) - }) + code := cmd.Run(args) + require.Equal(t, code, 0) + require.Empty(t, ui.ErrorWriter.String()) + } } func TestRoleCreateCommand_JSON(t *testing.T) { diff --git a/command/acl/role/formatter.go b/command/acl/role/formatter.go index 37a77e896af0..b000e88addd1 100644 --- a/command/acl/role/formatter.go +++ b/command/acl/role/formatter.go @@ -77,12 +77,6 @@ func (f *prettyFormatter) FormatRole(role *api.ACLRole) (string, error) { } } } - if len(role.NodeIdentities) > 0 { - buffer.WriteString(fmt.Sprintln("Node Identities:")) - for _, nodeid := range role.NodeIdentities { - buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) - } - } return buffer.String(), nil } @@ -128,13 +122,6 @@ func (f *prettyFormatter) formatRoleListEntry(role *api.ACLRole) string { } } - if len(role.NodeIdentities) > 0 { - buffer.WriteString(fmt.Sprintln(" Node Identities:")) - for _, nodeid := range role.NodeIdentities { - buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) - } - } - return buffer.String() } diff --git a/command/acl/role/testdata/FormatRole/basic.json.golden b/command/acl/role/testdata/FormatRole/basic.json.golden deleted file mode 100644 index a9c8d6c48721..000000000000 --- a/command/acl/role/testdata/FormatRole/basic.json.golden +++ /dev/null @@ -1,8 +0,0 @@ -{ - "ID": "bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852", - "Name": "basic", - "Description": "test role", - "Hash": "YWJjZGVmZ2g=", - "CreateIndex": 42, - "ModifyIndex": 100 -} \ No newline at end of file diff --git a/command/acl/role/testdata/FormatRole/basic.pretty-meta.golden b/command/acl/role/testdata/FormatRole/basic.pretty-meta.golden deleted file mode 100644 index 31ba775f6f88..000000000000 --- a/command/acl/role/testdata/FormatRole/basic.pretty-meta.golden +++ /dev/null @@ -1,6 +0,0 @@ -ID: bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852 -Name: basic -Description: test role -Hash: 6162636465666768 -Create Index: 42 -Modify Index: 100 diff --git a/command/acl/role/testdata/FormatRole/basic.pretty.golden b/command/acl/role/testdata/FormatRole/basic.pretty.golden deleted file mode 100644 index 56a4105ea1d8..000000000000 --- a/command/acl/role/testdata/FormatRole/basic.pretty.golden +++ /dev/null @@ -1,3 +0,0 @@ -ID: bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852 -Name: basic -Description: test role diff --git a/command/acl/role/testdata/FormatRole/complex.json.golden b/command/acl/role/testdata/FormatRole/complex.json.golden deleted file mode 100644 index b8d9b64950c0..000000000000 --- a/command/acl/role/testdata/FormatRole/complex.json.golden +++ /dev/null @@ -1,33 +0,0 @@ -{ - "ID": "c29c4ee4-bca6-474e-be37-7d9606f9582a", - "Name": "complex", - "Description": "test role complex", - "Policies": [ - { - "ID": "beb04680-815b-4d7c-9e33-3d707c24672c", - "Name": "hobbiton" - }, - { - "ID": "18788457-584c-4812-80d3-23d403148a90", - "Name": "bywater" - } - ], - "ServiceIdentities": [ - { - "ServiceName": "gardener", - "Datacenters": [ - "middleearth-northwest" - ] - } - ], - "NodeIdentities": [ - { - "NodeName": "bagend", - "Datacenter": "middleearth-northwest" - } - ], - "Hash": "YWJjZGVmZ2g=", - "CreateIndex": 5, - "ModifyIndex": 10, - "Namespace": "foo" -} \ No newline at end of file diff --git a/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden b/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden deleted file mode 100644 index 56e61f7780fe..000000000000 --- a/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden +++ /dev/null @@ -1,14 +0,0 @@ -ID: c29c4ee4-bca6-474e-be37-7d9606f9582a -Name: complex -Namespace: foo -Description: test role complex -Hash: 6162636465666768 -Create Index: 5 -Modify Index: 10 -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Service Identities: - gardener (Datacenters: middleearth-northwest) -Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/role/testdata/FormatRole/complex.pretty.golden b/command/acl/role/testdata/FormatRole/complex.pretty.golden deleted file mode 100644 index b3d347ed00cc..000000000000 --- a/command/acl/role/testdata/FormatRole/complex.pretty.golden +++ /dev/null @@ -1,11 +0,0 @@ -ID: c29c4ee4-bca6-474e-be37-7d9606f9582a -Name: complex -Namespace: foo -Description: test role complex -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Service Identities: - gardener (Datacenters: middleearth-northwest) -Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/role/testdata/FormatRoleList/basic.json.golden b/command/acl/role/testdata/FormatRoleList/basic.json.golden deleted file mode 100644 index daa313499271..000000000000 --- a/command/acl/role/testdata/FormatRoleList/basic.json.golden +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "ID": "bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852", - "Name": "basic", - "Description": "test role", - "Hash": "YWJjZGVmZ2g=", - "CreateIndex": 42, - "ModifyIndex": 100 - } -] \ No newline at end of file diff --git a/command/acl/role/testdata/FormatRoleList/basic.pretty-meta.golden b/command/acl/role/testdata/FormatRoleList/basic.pretty-meta.golden deleted file mode 100644 index b2fbc3d6ef23..000000000000 --- a/command/acl/role/testdata/FormatRoleList/basic.pretty-meta.golden +++ /dev/null @@ -1,6 +0,0 @@ -basic: - ID: bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852 - Description: test role - Hash: 6162636465666768 - Create Index: 42 - Modify Index: 100 diff --git a/command/acl/role/testdata/FormatRoleList/basic.pretty.golden b/command/acl/role/testdata/FormatRoleList/basic.pretty.golden deleted file mode 100644 index 587392e7b10f..000000000000 --- a/command/acl/role/testdata/FormatRoleList/basic.pretty.golden +++ /dev/null @@ -1,3 +0,0 @@ -basic: - ID: bd6c9fb0-2d1a-4b96-acaf-669f5d7e7852 - Description: test role diff --git a/command/acl/role/testdata/FormatRoleList/complex.json.golden b/command/acl/role/testdata/FormatRoleList/complex.json.golden deleted file mode 100644 index 58c6d850b85d..000000000000 --- a/command/acl/role/testdata/FormatRoleList/complex.json.golden +++ /dev/null @@ -1,35 +0,0 @@ -[ - { - "ID": "c29c4ee4-bca6-474e-be37-7d9606f9582a", - "Name": "complex", - "Description": "test role complex", - "Policies": [ - { - "ID": "beb04680-815b-4d7c-9e33-3d707c24672c", - "Name": "hobbiton" - }, - { - "ID": "18788457-584c-4812-80d3-23d403148a90", - "Name": "bywater" - } - ], - "ServiceIdentities": [ - { - "ServiceName": "gardener", - "Datacenters": [ - "middleearth-northwest" - ] - } - ], - "NodeIdentities": [ - { - "NodeName": "bagend", - "Datacenter": "middleearth-northwest" - } - ], - "Hash": "YWJjZGVmZ2g=", - "CreateIndex": 5, - "ModifyIndex": 10, - "Namespace": "foo" - } -] \ No newline at end of file diff --git a/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden b/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden deleted file mode 100644 index 76355e91dddc..000000000000 --- a/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden +++ /dev/null @@ -1,14 +0,0 @@ -complex: - ID: c29c4ee4-bca6-474e-be37-7d9606f9582a - Namespace: foo - Description: test role complex - Hash: 6162636465666768 - Create Index: 5 - Modify Index: 10 - Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater - Service Identities: - gardener (Datacenters: middleearth-northwest) - Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/role/testdata/FormatRoleList/complex.pretty.golden b/command/acl/role/testdata/FormatRoleList/complex.pretty.golden deleted file mode 100644 index ab2b0c87f8fe..000000000000 --- a/command/acl/role/testdata/FormatRoleList/complex.pretty.golden +++ /dev/null @@ -1,11 +0,0 @@ -complex: - ID: c29c4ee4-bca6-474e-be37-7d9606f9582a - Namespace: foo - Description: test role complex - Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater - Service Identities: - gardener (Datacenters: middleearth-northwest) - Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/role/update/role_update.go b/command/acl/role/update/role_update.go index afbadeb20776..a26858e29c6a 100644 --- a/command/acl/role/update/role_update.go +++ b/command/acl/role/update/role_update.go @@ -30,7 +30,6 @@ type cmd struct { policyIDs []string policyNames []string serviceIdents []string - nodeIdents []string noMerge bool showMeta bool @@ -53,9 +52,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.serviceIdents), "service-identity", "Name of a "+ "service identity to use for this role. May be specified multiple times. Format is "+ "the SERVICENAME or SERVICENAME:DATACENTER1,DATACENTER2,...") - c.flags.Var((*flags.AppendSliceValue)(&c.nodeIdents), "node-identity", "Name of a "+ - "node identity to use for this role. May be specified multiple times. Format is "+ - "NODENAME:DATACENTER") c.flags.BoolVar(&c.noMerge, "no-merge", false, "Do not merge the current role "+ "information with what is provided to the command. Instead overwrite all fields "+ "with the exception of the role ID which is immutable.") @@ -101,12 +97,6 @@ func (c *cmd) Run(args []string) int { return 1 } - parsedNodeIdents, err := acl.ExtractNodeIdentities(c.nodeIdents) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - // Read the current role in both cases so we can fail better if not found. currentRole, _, err := client.ACL().RoleRead(roleID, nil) if err != nil { @@ -124,7 +114,6 @@ func (c *cmd) Run(args []string) int { Name: c.name, Description: c.description, ServiceIdentities: parsedServiceIdents, - NodeIdentities: parsedNodeIdents, } for _, policyName := range c.policyNames { @@ -203,20 +192,6 @@ func (c *cmd) Run(args []string) int { r.ServiceIdentities = append(r.ServiceIdentities, svcid) } } - - for _, nodeid := range parsedNodeIdents { - found := false - for _, link := range r.NodeIdentities { - if link.NodeName == nodeid.NodeName && link.Datacenter != nodeid.Datacenter { - found = true - break - } - } - - if !found { - r.NodeIdentities = append(r.NodeIdentities, nodeid) - } - } } r, _, err = client.ACL().RoleUpdate(r, nil) diff --git a/command/acl/role/update/role_update_test.go b/command/acl/role/update/role_update_test.go index c7c59bd973b1..0e08c093ace4 100644 --- a/command/acl/role/update/role_update_test.go +++ b/command/acl/role/update/role_update_test.go @@ -71,19 +71,6 @@ func TestRoleUpdateCommand(t *testing.T) { ) require.NoError(t, err) - run := func(t *testing.T, args []string) *api.ACLRole { - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(append(args, "-format=json", "-http-addr="+a.HTTPAddr())) - require.Equal(t, 0, code, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - var role api.ACLRole - require.NoError(t, json.Unmarshal(ui.OutputWriter.Bytes(), &role)) - return &role - } - t.Run("update a role that does not exist", func(t *testing.T) { fakeID, err := uuid.GenerateUUID() require.NoError(t, err) @@ -104,12 +91,19 @@ func TestRoleUpdateCommand(t *testing.T) { }) t.Run("update with policy by name", func(t *testing.T) { - _ = run(t, []string{ + ui := cli.NewMockUi() + cmd := New(ui) + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-id=" + role.ID, "-token=root", "-policy-name=" + policy1.Name, "-description=test role edited", - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) + require.Empty(t, ui.ErrorWriter.String()) role, _, err := client.ACL().RoleRead( role.ID, @@ -125,11 +119,18 @@ func TestRoleUpdateCommand(t *testing.T) { t.Run("update with policy by id", func(t *testing.T) { // also update with no description shouldn't delete the current // description - _ = run(t, []string{ + ui := cli.NewMockUi() + cmd := New(ui) + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-id=" + role.ID, "-token=root", "-policy-id=" + policy2.ID, - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) + require.Empty(t, ui.ErrorWriter.String()) role, _, err := client.ACL().RoleRead( role.ID, @@ -143,11 +144,18 @@ func TestRoleUpdateCommand(t *testing.T) { }) t.Run("update with service identity", func(t *testing.T) { - _ = run(t, []string{ + ui := cli.NewMockUi() + cmd := New(ui) + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-id=" + role.ID, "-token=root", "-service-identity=web", - }) + } + + code := cmd.Run(args) + require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) + require.Empty(t, ui.ErrorWriter.String()) role, _, err := client.ACL().RoleRead( role.ID, @@ -161,29 +169,18 @@ func TestRoleUpdateCommand(t *testing.T) { }) t.Run("update with service identity scoped to 2 DCs", func(t *testing.T) { - _ = run(t, []string{ + ui := cli.NewMockUi() + cmd := New(ui) + args := []string{ + "-http-addr=" + a.HTTPAddr(), "-id=" + role.ID, "-token=root", "-service-identity=db:abc,xyz", - }) - - role, _, err := client.ACL().RoleRead( - role.ID, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, role) - require.Equal(t, "test role edited", role.Description) - require.Len(t, role.Policies, 2) - require.Len(t, role.ServiceIdentities, 3) - }) + } - t.Run("update with node identity", func(t *testing.T) { - _ = run(t, []string{ - "-id=" + role.ID, - "-token=root", - "-node-identity=foo:bar", - }) + code := cmd.Run(args) + require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) + require.Empty(t, ui.ErrorWriter.String()) role, _, err := client.ACL().RoleRead( role.ID, @@ -194,7 +191,6 @@ func TestRoleUpdateCommand(t *testing.T) { require.Equal(t, "test role edited", role.Description) require.Len(t, role.Policies, 2) require.Len(t, role.ServiceIdentities, 3) - require.Len(t, role.NodeIdentities, 1) }) } diff --git a/command/acl/token/create/token_create.go b/command/acl/token/create/token_create.go index 14bac71afadd..03e04e5331aa 100644 --- a/command/acl/token/create/token_create.go +++ b/command/acl/token/create/token_create.go @@ -33,7 +33,6 @@ type cmd struct { roleIDs []string roleNames []string serviceIdents []string - nodeIdents []string expirationTTL time.Duration local bool showMeta bool @@ -61,9 +60,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.serviceIdents), "service-identity", "Name of a "+ "service identity to use for this token. May be specified multiple times. Format is "+ "the SERVICENAME or SERVICENAME:DATACENTER1,DATACENTER2,...") - c.flags.Var((*flags.AppendSliceValue)(&c.nodeIdents), "node-identity", "Name of a "+ - "node identity to use for this token. May be specified multiple times. Format is "+ - "NODENAME:DATACENTER") c.flags.DurationVar(&c.expirationTTL, "expires-ttl", 0, "Duration of time this "+ "token should be valid for") c.flags.StringVar( @@ -86,8 +82,8 @@ func (c *cmd) Run(args []string) int { if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.roleNames) == 0 && len(c.roleIDs) == 0 && - len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 { - c.UI.Error(fmt.Sprintf("Cannot create a token without specifying -policy-name, -policy-id, -role-name, -role-id, -service-identity, or -node-identity at least once")) + len(c.serviceIdents) == 0 { + c.UI.Error(fmt.Sprintf("Cannot create a token without specifying -policy-name, -policy-id, -role-name, -role-id, or -service-identity at least once")) return 1 } @@ -114,13 +110,6 @@ func (c *cmd) Run(args []string) int { } newToken.ServiceIdentities = parsedServiceIdents - parsedNodeIdents, err := acl.ExtractNodeIdentities(c.nodeIdents) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - newToken.NodeIdentities = parsedNodeIdents - for _, policyName := range c.policyNames { // We could resolve names to IDs here but there isn't any reason why its would be better // than allowing the agent to do it. diff --git a/command/acl/token/create/token_create_test.go b/command/acl/token/create/token_create_test.go index a128c2f14b95..464771611b48 100644 --- a/command/acl/token/create/token_create_test.go +++ b/command/acl/token/create/token_create_test.go @@ -24,13 +24,13 @@ func TestTokenCreateCommand_noTabs(t *testing.T) { func TestTokenCreateCommand_Pretty(t *testing.T) { t.Parallel() + require := require.New(t) testDir := testutil.TempDir(t, "acl") defer os.RemoveAll(testDir) a := agent.NewTestAgent(t, ` primary_datacenter = "dc1" - node_name = "test-node" acl { enabled = true tokens { @@ -41,6 +41,9 @@ func TestTokenCreateCommand_Pretty(t *testing.T) { defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") + ui := cli.NewMockUi() + cmd := New(ui) + // Create a policy client := a.Client() @@ -48,75 +51,66 @@ func TestTokenCreateCommand_Pretty(t *testing.T) { &api.ACLPolicy{Name: "test-policy"}, &api.WriteOptions{Token: "root"}, ) - require.NoError(t, err) - - run := func(t *testing.T, args []string) *api.ACLToken { - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(append(args, "-format=json")) - require.Equal(t, 0, code) - require.Empty(t, ui.ErrorWriter.String()) - - var token api.ACLToken - require.NoError(t, json.Unmarshal(ui.OutputWriter.Bytes(), &token)) - return &token - } + require.NoError(err) // create with policy by name - t.Run("policy-name", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ "-http-addr=" + a.HTTPAddr(), "-token=root", "-policy-name=" + policy.Name, "-description=test token", - }) - }) + } + + code := cmd.Run(args) + require.Equal(code, 0) + require.Empty(ui.ErrorWriter.String()) + } // create with policy by id - t.Run("policy-id", func(t *testing.T) { - _ = run(t, []string{ + { + args := []string{ "-http-addr=" + a.HTTPAddr(), "-token=root", "-policy-id=" + policy.ID, "-description=test token", - }) - }) - - // create with a node identity - t.Run("node-identity", func(t *testing.T) { - token := run(t, []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-node-identity=" + a.Config.NodeName + ":" + a.Config.Datacenter, - }) - - conf := api.DefaultConfig() - conf.Address = a.HTTPAddr() - conf.Token = token.SecretID - client, err := api.NewClient(conf) - require.NoError(t, err) + } - nodes, _, err := client.Catalog().Nodes(nil) - require.NoError(t, err) - require.Len(t, nodes, 1) - require.Equal(t, a.Config.NodeName, nodes[0].Node) - }) + code := cmd.Run(args) + require.Empty(ui.ErrorWriter.String()) + require.Equal(code, 0) + } // create with accessor and secret - t.Run("predefined-ids", func(t *testing.T) { - token := run(t, []string{ + { + args := []string{ "-http-addr=" + a.HTTPAddr(), "-token=root", "-policy-id=" + policy.ID, "-description=test token", "-accessor=3d852bb8-5153-4388-a3ca-8ca78661889f", "-secret=3a69a8d8-c4d4-485d-9b19-b5b61648ea0c", - }) + } + + code := cmd.Run(args) + require.Empty(ui.ErrorWriter.String()) + require.Equal(code, 0) - require.Equal(t, "3d852bb8-5153-4388-a3ca-8ca78661889f", token.AccessorID) - require.Equal(t, "3a69a8d8-c4d4-485d-9b19-b5b61648ea0c", token.SecretID) - }) + conf := api.DefaultConfig() + conf.Address = a.HTTPAddr() + conf.Token = "root" + + // going to use the API client to grab the token - we could potentially try to grab the values + // out of the command output but this seems easier. + client, err := api.NewClient(conf) + require.NoError(err) + require.NotNil(client) + + token, _, err := client.ACL().TokenRead("3d852bb8-5153-4388-a3ca-8ca78661889f", nil) + require.NoError(err) + require.Equal("3d852bb8-5153-4388-a3ca-8ca78661889f", token.AccessorID) + require.Equal("3a69a8d8-c4d4-485d-9b19-b5b61648ea0c", token.SecretID) + } } func TestTokenCreateCommand_JSON(t *testing.T) { diff --git a/command/acl/token/formatter.go b/command/acl/token/formatter.go index 790b9f73b747..d5bb781c5e91 100644 --- a/command/acl/token/formatter.go +++ b/command/acl/token/formatter.go @@ -91,12 +91,6 @@ func (f *prettyFormatter) FormatToken(token *api.ACLToken) (string, error) { } } } - if len(token.NodeIdentities) > 0 { - buffer.WriteString(fmt.Sprintln("Node Identities:")) - for _, nodeid := range token.NodeIdentities { - buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) - } - } if token.Rules != "" { buffer.WriteString(fmt.Sprintln("Rules:")) buffer.WriteString(fmt.Sprintln(token.Rules)) @@ -165,16 +159,6 @@ func (f *prettyFormatter) formatTokenListEntry(token *api.ACLTokenListEntry) str } } } - if len(token.NodeIdentities) > 0 { - buffer.WriteString(fmt.Sprintln("Service Identities:")) - for _, svcid := range token.ServiceIdentities { - if len(svcid.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(" %s (Datacenters: %s)\n", svcid.ServiceName, strings.Join(svcid.Datacenters, ", "))) - } else { - buffer.WriteString(fmt.Sprintf(" %s (Datacenters: all)\n", svcid.ServiceName)) - } - } - } return buffer.String() } diff --git a/command/acl/token/testdata/FormatToken/basic.json.golden b/command/acl/token/testdata/FormatToken/basic.json.golden deleted file mode 100644 index 6562a9a88a4a..000000000000 --- a/command/acl/token/testdata/FormatToken/basic.json.golden +++ /dev/null @@ -1,10 +0,0 @@ -{ - "CreateIndex": 42, - "ModifyIndex": 100, - "AccessorID": "fbd2447f-7479-4329-ad13-b021d74f86ba", - "SecretID": "869c6e91-4de9-4dab-b56e-87548435f9c6", - "Description": "test token", - "Local": false, - "CreateTime": "2020-05-22T18:52:31Z", - "Hash": "YWJjZGVmZ2g=" -} \ No newline at end of file diff --git a/command/acl/token/testdata/FormatToken/basic.pretty-meta.golden b/command/acl/token/testdata/FormatToken/basic.pretty-meta.golden deleted file mode 100644 index 232176e72d1c..000000000000 --- a/command/acl/token/testdata/FormatToken/basic.pretty-meta.golden +++ /dev/null @@ -1,8 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -SecretID: 869c6e91-4de9-4dab-b56e-87548435f9c6 -Description: test token -Local: false -Create Time: 2020-05-22 18:52:31 +0000 UTC -Hash: 6162636465666768 -Create Index: 42 -Modify Index: 100 diff --git a/command/acl/token/testdata/FormatToken/basic.pretty.golden b/command/acl/token/testdata/FormatToken/basic.pretty.golden deleted file mode 100644 index 44b9768945b9..000000000000 --- a/command/acl/token/testdata/FormatToken/basic.pretty.golden +++ /dev/null @@ -1,5 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -SecretID: 869c6e91-4de9-4dab-b56e-87548435f9c6 -Description: test token -Local: false -Create Time: 2020-05-22 18:52:31 +0000 UTC diff --git a/command/acl/token/testdata/FormatToken/complex.json.golden b/command/acl/token/testdata/FormatToken/complex.json.golden deleted file mode 100644 index 4462e29b1bff..000000000000 --- a/command/acl/token/testdata/FormatToken/complex.json.golden +++ /dev/null @@ -1,47 +0,0 @@ -{ - "CreateIndex": 5, - "ModifyIndex": 10, - "AccessorID": "fbd2447f-7479-4329-ad13-b021d74f86ba", - "SecretID": "869c6e91-4de9-4dab-b56e-87548435f9c6", - "Description": "test token", - "Policies": [ - { - "ID": "beb04680-815b-4d7c-9e33-3d707c24672c", - "Name": "hobbiton" - }, - { - "ID": "18788457-584c-4812-80d3-23d403148a90", - "Name": "bywater" - } - ], - "Roles": [ - { - "ID": "3b0a78fe-b9c3-40de-b8ea-7d4d6674b366", - "Name": "shire" - }, - { - "ID": "6c9d1e1d-34bc-4d55-80f3-add0890ad791", - "Name": "west-farthing" - } - ], - "ServiceIdentities": [ - { - "ServiceName": "gardener", - "Datacenters": [ - "middleearth-northwest" - ] - } - ], - "NodeIdentities": [ - { - "NodeName": "bagend", - "Datacenter": "middleearth-northwest" - } - ], - "Local": false, - "AuthMethod": "bar", - "ExpirationTime": "2020-05-22T19:52:31Z", - "CreateTime": "2020-05-22T18:52:31Z", - "Hash": "YWJjZGVmZ2g=", - "Namespace": "foo" -} \ No newline at end of file diff --git a/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden b/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden deleted file mode 100644 index dfce5577130a..000000000000 --- a/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden +++ /dev/null @@ -1,21 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -SecretID: 869c6e91-4de9-4dab-b56e-87548435f9c6 -Namespace: foo -Description: test token -Local: false -Auth Method: bar -Create Time: 2020-05-22 18:52:31 +0000 UTC -Expiration Time: 2020-05-22 19:52:31 +0000 UTC -Hash: 6162636465666768 -Create Index: 5 -Modify Index: 10 -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Roles: - 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 - shire - 6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing -Service Identities: - gardener (Datacenters: middleearth-northwest) -Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/token/testdata/FormatToken/complex.pretty.golden b/command/acl/token/testdata/FormatToken/complex.pretty.golden deleted file mode 100644 index 4437281b8d83..000000000000 --- a/command/acl/token/testdata/FormatToken/complex.pretty.golden +++ /dev/null @@ -1,18 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -SecretID: 869c6e91-4de9-4dab-b56e-87548435f9c6 -Namespace: foo -Description: test token -Local: false -Auth Method: bar -Create Time: 2020-05-22 18:52:31 +0000 UTC -Expiration Time: 2020-05-22 19:52:31 +0000 UTC -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Roles: - 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 - shire - 6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing -Service Identities: - gardener (Datacenters: middleearth-northwest) -Node Identities: - bagend (Datacenter: middleearth-northwest) diff --git a/command/acl/token/testdata/FormatToken/legacy.json.golden b/command/acl/token/testdata/FormatToken/legacy.json.golden deleted file mode 100644 index 71536fc2fe93..000000000000 --- a/command/acl/token/testdata/FormatToken/legacy.json.golden +++ /dev/null @@ -1,10 +0,0 @@ -{ - "CreateIndex": 0, - "ModifyIndex": 0, - "AccessorID": "8acc7486-ca54-4d3c-9aed-5cd85651b0ee", - "SecretID": "legacy-secret", - "Description": "legacy", - "Local": false, - "CreateTime": "0001-01-01T00:00:00Z", - "Rules": "operator = \"read\"" -} \ No newline at end of file diff --git a/command/acl/token/testdata/FormatToken/legacy.pretty-meta.golden b/command/acl/token/testdata/FormatToken/legacy.pretty-meta.golden deleted file mode 100644 index cb477af5a5fd..000000000000 --- a/command/acl/token/testdata/FormatToken/legacy.pretty-meta.golden +++ /dev/null @@ -1,10 +0,0 @@ -AccessorID: 8acc7486-ca54-4d3c-9aed-5cd85651b0ee -SecretID: legacy-secret -Description: legacy -Local: false -Create Time: 0001-01-01 00:00:00 +0000 UTC -Hash: -Create Index: 0 -Modify Index: 0 -Rules: -operator = "read" diff --git a/command/acl/token/testdata/FormatToken/legacy.pretty.golden b/command/acl/token/testdata/FormatToken/legacy.pretty.golden deleted file mode 100644 index ea6c5b715953..000000000000 --- a/command/acl/token/testdata/FormatToken/legacy.pretty.golden +++ /dev/null @@ -1,7 +0,0 @@ -AccessorID: 8acc7486-ca54-4d3c-9aed-5cd85651b0ee -SecretID: legacy-secret -Description: legacy -Local: false -Create Time: 0001-01-01 00:00:00 +0000 UTC -Rules: -operator = "read" diff --git a/command/acl/token/testdata/FormatTokenList/basic.json.golden b/command/acl/token/testdata/FormatTokenList/basic.json.golden deleted file mode 100644 index 180f84c52e84..000000000000 --- a/command/acl/token/testdata/FormatTokenList/basic.json.golden +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "CreateIndex": 42, - "ModifyIndex": 100, - "AccessorID": "fbd2447f-7479-4329-ad13-b021d74f86ba", - "Description": "test token", - "Local": false, - "CreateTime": "2020-05-22T18:52:31Z", - "Hash": "YWJjZGVmZ2g=", - "Legacy": false - } -] \ No newline at end of file diff --git a/command/acl/token/testdata/FormatTokenList/basic.pretty-meta.golden b/command/acl/token/testdata/FormatTokenList/basic.pretty-meta.golden deleted file mode 100644 index ab00607741e0..000000000000 --- a/command/acl/token/testdata/FormatTokenList/basic.pretty-meta.golden +++ /dev/null @@ -1,8 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -Description: test token -Local: false -Create Time: 2020-05-22 18:52:31 +0000 UTC -Legacy: false -Hash: 6162636465666768 -Create Index: 42 -Modify Index: 100 diff --git a/command/acl/token/testdata/FormatTokenList/basic.pretty.golden b/command/acl/token/testdata/FormatTokenList/basic.pretty.golden deleted file mode 100644 index c13d1babb108..000000000000 --- a/command/acl/token/testdata/FormatTokenList/basic.pretty.golden +++ /dev/null @@ -1,5 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -Description: test token -Local: false -Create Time: 2020-05-22 18:52:31 +0000 UTC -Legacy: false diff --git a/command/acl/token/testdata/FormatTokenList/complex.json.golden b/command/acl/token/testdata/FormatTokenList/complex.json.golden deleted file mode 100644 index abaaac0caa9c..000000000000 --- a/command/acl/token/testdata/FormatTokenList/complex.json.golden +++ /dev/null @@ -1,49 +0,0 @@ -[ - { - "CreateIndex": 5, - "ModifyIndex": 10, - "AccessorID": "fbd2447f-7479-4329-ad13-b021d74f86ba", - "Description": "test token", - "Policies": [ - { - "ID": "beb04680-815b-4d7c-9e33-3d707c24672c", - "Name": "hobbiton" - }, - { - "ID": "18788457-584c-4812-80d3-23d403148a90", - "Name": "bywater" - } - ], - "Roles": [ - { - "ID": "3b0a78fe-b9c3-40de-b8ea-7d4d6674b366", - "Name": "shire" - }, - { - "ID": "6c9d1e1d-34bc-4d55-80f3-add0890ad791", - "Name": "west-farthing" - } - ], - "ServiceIdentities": [ - { - "ServiceName": "gardener", - "Datacenters": [ - "middleearth-northwest" - ] - } - ], - "NodeIdentities": [ - { - "NodeName": "bagend", - "Datacenter": "middleearth-northwest" - } - ], - "Local": false, - "AuthMethod": "bar", - "ExpirationTime": "2020-05-22T19:52:31Z", - "CreateTime": "2020-05-22T18:52:31Z", - "Hash": "YWJjZGVmZ2g=", - "Legacy": false, - "Namespace": "foo" - } -] \ No newline at end of file diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden deleted file mode 100644 index 17cd91243845..000000000000 --- a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden +++ /dev/null @@ -1,21 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -Namespace: foo -Description: test token -Local: false -Auth Method: bar -Create Time: 2020-05-22 18:52:31 +0000 UTC -Expiration Time: 2020-05-22 19:52:31 +0000 UTC -Legacy: false -Hash: 6162636465666768 -Create Index: 5 -Modify Index: 10 -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Roles: - 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 - shire - 6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing -Service Identities: - gardener (Datacenters: middleearth-northwest) -Service Identities: - gardener (Datacenters: middleearth-northwest) diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty.golden deleted file mode 100644 index e6965f33b5f1..000000000000 --- a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden +++ /dev/null @@ -1,18 +0,0 @@ -AccessorID: fbd2447f-7479-4329-ad13-b021d74f86ba -Namespace: foo -Description: test token -Local: false -Auth Method: bar -Create Time: 2020-05-22 18:52:31 +0000 UTC -Expiration Time: 2020-05-22 19:52:31 +0000 UTC -Legacy: false -Policies: - beb04680-815b-4d7c-9e33-3d707c24672c - hobbiton - 18788457-584c-4812-80d3-23d403148a90 - bywater -Roles: - 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 - shire - 6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing -Service Identities: - gardener (Datacenters: middleearth-northwest) -Service Identities: - gardener (Datacenters: middleearth-northwest) diff --git a/command/acl/token/testdata/FormatTokenList/legacy.json.golden b/command/acl/token/testdata/FormatTokenList/legacy.json.golden deleted file mode 100644 index d639b8025248..000000000000 --- a/command/acl/token/testdata/FormatTokenList/legacy.json.golden +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "CreateIndex": 0, - "ModifyIndex": 0, - "AccessorID": "8acc7486-ca54-4d3c-9aed-5cd85651b0ee", - "Description": "legacy", - "Local": false, - "CreateTime": "0001-01-01T00:00:00Z", - "Hash": null, - "Legacy": true - } -] \ No newline at end of file diff --git a/command/acl/token/testdata/FormatTokenList/legacy.pretty-meta.golden b/command/acl/token/testdata/FormatTokenList/legacy.pretty-meta.golden deleted file mode 100644 index 85532190061a..000000000000 --- a/command/acl/token/testdata/FormatTokenList/legacy.pretty-meta.golden +++ /dev/null @@ -1,8 +0,0 @@ -AccessorID: 8acc7486-ca54-4d3c-9aed-5cd85651b0ee -Description: legacy -Local: false -Create Time: 0001-01-01 00:00:00 +0000 UTC -Legacy: true -Hash: -Create Index: 0 -Modify Index: 0 diff --git a/command/acl/token/testdata/FormatTokenList/legacy.pretty.golden b/command/acl/token/testdata/FormatTokenList/legacy.pretty.golden deleted file mode 100644 index ee2a5299b56d..000000000000 --- a/command/acl/token/testdata/FormatTokenList/legacy.pretty.golden +++ /dev/null @@ -1,5 +0,0 @@ -AccessorID: 8acc7486-ca54-4d3c-9aed-5cd85651b0ee -Description: legacy -Local: false -Create Time: 0001-01-01 00:00:00 +0000 UTC -Legacy: true diff --git a/command/acl/token/update/token_update.go b/command/acl/token/update/token_update.go index 2a5592ab3007..5e2c2224cd7b 100644 --- a/command/acl/token/update/token_update.go +++ b/command/acl/token/update/token_update.go @@ -30,12 +30,10 @@ type cmd struct { roleIDs []string roleNames []string serviceIdents []string - nodeIdents []string description string mergePolicies bool mergeRoles bool mergeServiceIdents bool - mergeNodeIdents bool showMeta bool upgradeLegacy bool format string @@ -51,8 +49,6 @@ func (c *cmd) init() { "with the existing roles") c.flags.BoolVar(&c.mergeServiceIdents, "merge-service-identities", false, "Merge the new service identities "+ "with the existing service identities") - c.flags.BoolVar(&c.mergeNodeIdents, "merge-node-identities", false, "Merge the new node identities "+ - "with the existing node identities") c.flags.StringVar(&c.tokenID, "id", "", "The Accessor ID of the token to update. "+ "It may be specified as a unique ID prefix but will error if the prefix "+ "matches multiple token Accessor IDs") @@ -68,9 +64,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.serviceIdents), "service-identity", "Name of a "+ "service identity to use for this token. May be specified multiple times. Format is "+ "the SERVICENAME or SERVICENAME:DATACENTER1,DATACENTER2,...") - c.flags.Var((*flags.AppendSliceValue)(&c.nodeIdents), "node-identity", "Name of a "+ - "node identity to use for this token. May be specified multiple times. Format is "+ - "NODENAME:DATACENTER") c.flags.BoolVar(&c.upgradeLegacy, "upgrade-legacy", false, "Add new polices "+ "to a legacy token replacing all existing rules. This will cause the legacy "+ "token to behave exactly like a new token but keep the same Secret.\n"+ @@ -146,12 +139,6 @@ func (c *cmd) Run(args []string) int { return 1 } - parsedNodeIdents, err := acl.ExtractNodeIdentities(c.nodeIdents) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - if c.mergePolicies { for _, policyName := range c.policyNames { found := false @@ -282,24 +269,6 @@ func (c *cmd) Run(args []string) int { t.ServiceIdentities = parsedServiceIdents } - if c.mergeNodeIdents { - for _, nodeid := range parsedNodeIdents { - found := false - for _, link := range t.NodeIdentities { - if link.NodeName == nodeid.NodeName && link.Datacenter == nodeid.Datacenter { - found = true - break - } - } - - if !found { - t.NodeIdentities = append(t.NodeIdentities, nodeid) - } - } - } else { - t.NodeIdentities = parsedNodeIdents - } - t, _, err = client.ACL().TokenUpdate(t, nil) if err != nil { c.UI.Error(fmt.Sprintf("Failed to update token %s: %v", tokenID, err)) diff --git a/website/pages/api-docs/acl/binding-rules.mdx b/website/pages/api-docs/acl/binding-rules.mdx index a896e73d7ba6..c02af9542f0a 100644 --- a/website/pages/api-docs/acl/binding-rules.mdx +++ b/website/pages/api-docs/acl/binding-rules.mdx @@ -63,17 +63,6 @@ The table below shows this endpoint's support for ] } ``` - - - `BindType=node` - The computed bind name value is used as an - `ACLNodeIdentity.NodeName` field in the token that is created. - - ```json - { ...other fields... - "NodeIdentities": [ - { "NodeName": "", "Datacenter": "" } - ] - } - ``` - `BindType=role` - The computed bind name value is used as a `RoleLink.Name` field in the token that is created. This binding rule will only apply if a @@ -243,18 +232,7 @@ The table below shows this endpoint's support for ] } ``` - - - `BindType=node` - The computed bind name value is used as an - `ACLNodeIdentity.NodeName` field in the token that is created. - ```json - { ...other fields... - "NodeIdentities": [ - { "NodeName": "", "Datacenter": "" } - ] - } - ``` - - `BindType=role` - The computed bind name value is used as a `RoleLink.Name` field in the token that is created. This binding rule will only apply if a role with the given name exists at login-time. If it does not then this @@ -416,7 +394,6 @@ $ curl -X GET http://127.0.0.1:8500/v1/acl/binding-rules "ID": "b4f0a0a3-69f2-7a4f-6bef-326034ace9fa", "Description": "example 2", "AuthMethod": "minikube-2", - "BindType": "service", "Selector": "serviceaccount.namespace==default", "BindName": "k8s-{{ serviceaccount.name }}", "CreateIndex": 18, diff --git a/website/pages/api-docs/acl/roles.mdx b/website/pages/api-docs/acl/roles.mdx index 544633fd0866..0b4797970c31 100644 --- a/website/pages/api-docs/acl/roles.mdx +++ b/website/pages/api-docs/acl/roles.mdx @@ -62,18 +62,6 @@ The table below shows this endpoint's support for policy is valid in all datacenters including those which do not yet exist but may in the future. -- `NodeIdentities` `(array)` - The list of [node - identities](/docs/acl/acl-system#acl-node-identities) that should be - applied to the role. Added in Consul 1.8.1. - - - `NodeName` `(string: )` - The name of the node. The name - must be no longer than 256 characters, must start and end with a lowercase - alphanumeric character, and can only contain lowercase alphanumeric - characters as well as `-` and `_`. - - - `Datacenter` `(string: )` - Specifies the nodes datacenter. This - will result in effective policy only being valid in that datacenter. - - `Namespace` `(string: "")` - Specifies the namespace to create the role. If not provided in the JSON body, the value of the `ns` URL query parameter or in the `X-Consul-Namespace` header will be used. @@ -102,12 +90,6 @@ The table below shows this endpoint's support for "ServiceName": "db", "Datacenters": ["dc1"] } - ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } ] } ``` @@ -142,12 +124,6 @@ $ curl -X PUT \ "Datacenters": ["dc1"] } ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } - ], "Hash": "mBWMIeX9zyUTdDMq8vWB0iYod+mKBArJoAhj6oPz3BI=", "CreateIndex": 57, "ModifyIndex": 57 @@ -212,12 +188,6 @@ $ curl -X GET http://127.0.0.1:8500/v1/acl/role/aa770e5b-8b0b-7fcf-e5a1-8535fcc3 "Datacenters": ["dc1"] } ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } - ], "Hash": "mBWMIeX9zyUTdDMq8vWB0iYod+mKBArJoAhj6oPz3BI=", "CreateIndex": 57, "ModifyIndex": 57 @@ -282,12 +252,6 @@ $ curl -X GET http://127.0.0.1:8500/v1/acl/role/name/example-role "Datacenters": ["dc1"] } ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } - ], "Hash": "mBWMIeX9zyUTdDMq8vWB0iYod+mKBArJoAhj6oPz3BI=", "CreateIndex": 57, "ModifyIndex": 57 @@ -335,10 +299,6 @@ The table below shows this endpoint's support for identities](/docs/acl/acl-system#acl-service-identities) that should be applied to the role. Added in Consul 1.5.0. -- `NodeIdentities` `(array)` - The list of [node - identities](/docs/acl/acl-system#acl-node-identities) that should be - applied to the role. Added in Consul 1.8.1. - - `Namespace` `(string: "")` - Specifies the namespace of the role to update. If not provided in the JSON body, the value of the `ns` URL query parameter or in the `X-Consul-Namespace` header will be used. @@ -360,12 +320,6 @@ The table below shows this endpoint's support for { "ServiceName": "db" } - ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } ] } ``` @@ -395,12 +349,6 @@ $ curl -X PUT \ "ServiceName": "db" } ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } - ], "Hash": "OtZUUKhInTLEqTPfNSSOYbRiSBKm3c4vI2p6MxZnGWc=", "CreateIndex": 14, "ModifyIndex": 28 @@ -527,12 +475,6 @@ $ curl -X GET http://127.0.0.1:8500/v1/acl/roles "Datacenters": ["dc1"] } ], - "NodeIdentities": [ - { - "NodeName": "node-1", - "Datacenter": "dc2" - } - ], "Hash": "mBWMIeX9zyUTdDMq8vWB0iYod+mKBArJoAhj6oPz3BI=", "CreateIndex": 57, "ModifyIndex": 57 diff --git a/website/pages/api-docs/acl/tokens.mdx b/website/pages/api-docs/acl/tokens.mdx index 5e77a3e2b0e1..d49d5ef883f3 100644 --- a/website/pages/api-docs/acl/tokens.mdx +++ b/website/pages/api-docs/acl/tokens.mdx @@ -74,18 +74,6 @@ The table below shows this endpoint's support for policy is valid in all datacenters including those which do not yet exist but may in the future. -- `NodeIdentities` `(array)` - The list of [node - identities](/docs/acl/acl-system#acl-node-identities) that should be - applied to the token. Added in Consul 1.8.1. - - - `NodeName` `(string: )` - The name of the node. The name - must be no longer than 256 characters, must start and end with a lowercase - alphanumeric character, and can only contain lowercase alphanumeric - characters as well as `-` and `_`. - - - `Datacenter` `(string: )` - Specifies the nodes datacenter. This - will result in effective policy only being valid in that datacenter. - - `Local` `(bool: false)` - If true, indicates that the token should not be replicated globally and instead be local to the current datacenter. @@ -335,18 +323,6 @@ The table below shows this endpoint's support for policy is valid in all datacenters including those which do not yet exist but may in the future. -- `NodeIdentities` `(array)` - The list of [node - identities](/docs/acl/acl-system#acl-node-identities) that should be - applied to the token. Added in Consul 1.8.1. - - - `NodeName` `(string: )` - The name of the node. The name - must be no longer than 256 characters, must start and end with a lowercase - alphanumeric character, and can only contain lowercase alphanumeric - characters as well as `-` and `_`. - - - `Datacenter` `(string: )` - Specifies the nodes datacenter. This - will result in effective policy only being valid in that datacenter. - - `Local` `(bool: false)` - If true, indicates that this token should not be replicated globally and instead be local to the current datacenter. This value must match the existing value or the request will return an error. diff --git a/website/pages/docs/acl/acl-system.mdx b/website/pages/docs/acl/acl-system.mdx index 3d384718f9d2..04ab4441f20f 100644 --- a/website/pages/docs/acl/acl-system.mdx +++ b/website/pages/docs/acl/acl-system.mdx @@ -45,13 +45,6 @@ may benefit from additional components in the ACL system: additional policy was attached, the contents of which are described further below. These are directly attached to tokens and roles and are not independently configured. (Added in Consul 1.5.0) - -- **ACL Node Identities** - Node identities are a policy template for - expressing a link to a policy suitable for use as an [Consul `agent` token - ](/docs/agent/options#acl_tokens_agent). At authorization time this acts like an - additional policy was attached, the contents of which are described further - below. These are directly attached to tokens and roles and are not - independently configured. (Added in Consul 1.8.1) - **ACL Auth Methods and Binding Rules** - To learn more about these topics, see the [auth methods documentation page](/docs/acl/auth-methods). @@ -130,38 +123,6 @@ examples of using a service identity. -> **Consul Enterprise Namespacing** - Service Identity rules will be scoped to the single namespace that the corresponding ACL Token or Role resides within. -### ACL Node Identities - --> Added in Consul 1.8.1 - -An ACL node identity is an [ACL policy](/docs/acl/acl-system#acl-policies) template for expressing a link to a policy -suitable for use as an [Consul `agent` token](/docs/agent/options#acl_tokens_agent). They are usable -on both tokens and roles and are composed of the following elements: - -- **Node Name** - The name of the node to grant access to. -- **Datacenter** - The datacenter that the node resides within. - -During the authorization process, the configured node identity is automatically -applied as a policy with the following preconfigured [ACL -rules](/docs/acl/acl-system#acl-rules-and-scope): - -```hcl -# Allow the agent to register its own node in the Catalog and update its network coordinates -node "" { - policy = "write" -} - -# Allows the agent to detect and diff services registered to itself. This is used during -# anti-entropy to reconcile difference between the agents knowledge of registered -# services and checks in comparison with what is known in the Catalog. -service_prefix "" { - policy = "read" -} -``` - --> **Consul Enterprise Namespacing** - Node Identities can only be applied to tokens and roles in the `default` namespace. -The synthetic policy rules allow for `service:read` permissions on all services in all namespaces. - ### ACL Roles -> Added in Consul 1.5.0