Remove legacy acl policies (#15922)
* remove legacy tokens * remove legacy acl policies * flatten test policies to *_prefix * address oss feedback re: phrasing and tests
This commit is contained in:
parent
060b7b7084
commit
9e99a30b77
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:breaking-change
|
||||||
|
acl: remove all functionality and references for legacy acl policies.
|
||||||
|
```
|
483
acl/acl_test.go
483
acl/acl_test.go
|
@ -7,31 +7,6 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func legacyPolicy(policy *Policy) *Policy {
|
|
||||||
return &Policy{
|
|
||||||
PolicyRules: PolicyRules{
|
|
||||||
Agents: policy.Agents,
|
|
||||||
AgentPrefixes: policy.Agents,
|
|
||||||
Nodes: policy.Nodes,
|
|
||||||
NodePrefixes: policy.Nodes,
|
|
||||||
Keys: policy.Keys,
|
|
||||||
KeyPrefixes: policy.Keys,
|
|
||||||
Services: policy.Services,
|
|
||||||
ServicePrefixes: policy.Services,
|
|
||||||
Sessions: policy.Sessions,
|
|
||||||
SessionPrefixes: policy.Sessions,
|
|
||||||
Events: policy.Events,
|
|
||||||
EventPrefixes: policy.Events,
|
|
||||||
PreparedQueries: policy.PreparedQueries,
|
|
||||||
PreparedQueryPrefixes: policy.PreparedQueries,
|
|
||||||
Keyring: policy.Keyring,
|
|
||||||
Operator: policy.Operator,
|
|
||||||
Mesh: policy.Mesh,
|
|
||||||
Peering: policy.Peering,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// The following 1 line functions are created to all conform to what
|
// The following 1 line functions are created to all conform to what
|
||||||
// can be stored in the aclCheck type to make defining ACL tests
|
// can be stored in the aclCheck type to make defining ACL tests
|
||||||
|
@ -561,7 +536,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "AgentBasicDefaultDeny",
|
name: "AgentBasicDefaultDeny",
|
||||||
defaultPolicy: DenyAll(),
|
defaultPolicy: DenyAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -577,8 +552,22 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "root",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadDenied", prefix: "ro", check: checkDenyAgentRead},
|
{name: "DefaultReadDenied", prefix: "ro", check: checkDenyAgentRead},
|
||||||
|
@ -601,7 +590,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "AgentBasicDefaultAllow",
|
name: "AgentBasicDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -617,8 +606,22 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "root",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadDenied", prefix: "ro", check: checkAllowAgentRead},
|
{name: "DefaultReadDenied", prefix: "ro", check: checkAllowAgentRead},
|
||||||
|
@ -641,7 +644,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "PreparedQueryDefaultAllow",
|
name: "PreparedQueryDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
PreparedQueries: []*PreparedQueryRule{
|
PreparedQueries: []*PreparedQueryRule{
|
||||||
{
|
{
|
||||||
|
@ -649,8 +652,14 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
PreparedQueryPrefixes: []*PreparedQueryRule{
|
||||||
|
{
|
||||||
|
Prefix: "other",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
// in version 1.2.1 and below this would have failed
|
// in version 1.2.1 and below this would have failed
|
||||||
|
@ -665,7 +674,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "AgentNestedDefaultDeny",
|
name: "AgentNestedDefaultDeny",
|
||||||
defaultPolicy: DenyAll(),
|
defaultPolicy: DenyAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -685,9 +694,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Node: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -707,8 +734,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadDenied", prefix: "nope", check: checkDenyAgentRead},
|
{name: "DefaultReadDenied", prefix: "nope", check: checkDenyAgentRead},
|
||||||
|
@ -745,7 +790,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "AgentNestedDefaultAllow",
|
name: "AgentNestedDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -765,9 +810,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Node: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Agents: []*AgentRule{
|
Agents: []*AgentRule{
|
||||||
{
|
{
|
||||||
|
@ -787,8 +850,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AgentPrefixes: []*AgentRule{
|
||||||
|
{
|
||||||
|
Node: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowAgentRead},
|
{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowAgentRead},
|
||||||
|
@ -1679,7 +1760,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "NodeDefaultDeny",
|
name: "NodeDefaultDeny",
|
||||||
defaultPolicy: DenyAll(),
|
defaultPolicy: DenyAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Nodes: []*NodeRule{
|
Nodes: []*NodeRule{
|
||||||
{
|
{
|
||||||
|
@ -1699,9 +1780,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NodePrefixes: []*NodeRule{
|
||||||
|
{
|
||||||
|
Name: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Name: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Nodes: []*NodeRule{
|
Nodes: []*NodeRule{
|
||||||
{
|
{
|
||||||
|
@ -1721,8 +1820,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NodePrefixes: []*NodeRule{
|
||||||
|
{
|
||||||
|
Name: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "ReadAllDenied", prefix: "", check: checkDenyNodeReadAll},
|
{name: "ReadAllDenied", prefix: "", check: checkDenyNodeReadAll},
|
||||||
|
@ -1760,7 +1877,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "NodeDefaultAllow",
|
name: "NodeDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Nodes: []*NodeRule{
|
Nodes: []*NodeRule{
|
||||||
{
|
{
|
||||||
|
@ -1780,9 +1897,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NodePrefixes: []*NodeRule{
|
||||||
|
{
|
||||||
|
Name: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Name: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Nodes: []*NodeRule{
|
Nodes: []*NodeRule{
|
||||||
{
|
{
|
||||||
|
@ -1802,8 +1937,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
NodePrefixes: []*NodeRule{
|
||||||
|
{
|
||||||
|
Name: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "ReadAllDenied", prefix: "", check: checkDenyNodeReadAll},
|
{name: "ReadAllDenied", prefix: "", check: checkDenyNodeReadAll},
|
||||||
|
@ -1841,7 +1994,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "SessionDefaultDeny",
|
name: "SessionDefaultDeny",
|
||||||
defaultPolicy: DenyAll(),
|
defaultPolicy: DenyAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Sessions: []*SessionRule{
|
Sessions: []*SessionRule{
|
||||||
{
|
{
|
||||||
|
@ -1861,9 +2014,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SessionPrefixes: []*SessionRule{
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Node: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Sessions: []*SessionRule{
|
Sessions: []*SessionRule{
|
||||||
{
|
{
|
||||||
|
@ -1883,8 +2054,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SessionPrefixes: []*SessionRule{
|
||||||
|
{
|
||||||
|
Node: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadDenied", prefix: "nope", check: checkDenySessionRead},
|
{name: "DefaultReadDenied", prefix: "nope", check: checkDenySessionRead},
|
||||||
|
@ -1921,7 +2110,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "SessionDefaultAllow",
|
name: "SessionDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Sessions: []*SessionRule{
|
Sessions: []*SessionRule{
|
||||||
{
|
{
|
||||||
|
@ -1941,9 +2130,27 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SessionPrefixes: []*SessionRule{
|
||||||
|
{
|
||||||
|
Node: "root-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Node: "root-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "root-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Sessions: []*SessionRule{
|
Sessions: []*SessionRule{
|
||||||
{
|
{
|
||||||
|
@ -1963,8 +2170,26 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SessionPrefixes: []*SessionRule{
|
||||||
|
{
|
||||||
|
Node: "child-nope",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-ro",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "child-rw",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: "override",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowSessionRead},
|
{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowSessionRead},
|
||||||
|
@ -2001,7 +2226,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "Parent",
|
name: "Parent",
|
||||||
defaultPolicy: DenyAll(),
|
defaultPolicy: DenyAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Keys: []*KeyRule{
|
Keys: []*KeyRule{
|
||||||
{
|
{
|
||||||
|
@ -2013,6 +2238,16 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyRead,
|
Policy: PolicyRead,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
KeyPrefixes: []*KeyRule{
|
||||||
|
{
|
||||||
|
Prefix: "foo/",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "bar/",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
},
|
||||||
PreparedQueries: []*PreparedQueryRule{
|
PreparedQueries: []*PreparedQueryRule{
|
||||||
{
|
{
|
||||||
Prefix: "other",
|
Prefix: "other",
|
||||||
|
@ -2023,6 +2258,16 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyRead,
|
Policy: PolicyRead,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
PreparedQueryPrefixes: []*PreparedQueryRule{
|
||||||
|
{
|
||||||
|
Prefix: "other",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "foo",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
},
|
||||||
Services: []*ServiceRule{
|
Services: []*ServiceRule{
|
||||||
{
|
{
|
||||||
Name: "other",
|
Name: "other",
|
||||||
|
@ -2033,9 +2278,19 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyRead,
|
Policy: PolicyRead,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ServicePrefixes: []*ServiceRule{
|
||||||
|
{
|
||||||
|
Name: "other",
|
||||||
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
}),
|
{
|
||||||
legacyPolicy(&Policy{
|
Name: "foo",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Keys: []*KeyRule{
|
Keys: []*KeyRule{
|
||||||
{
|
{
|
||||||
|
@ -2051,20 +2306,46 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyRead,
|
Policy: PolicyRead,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
KeyPrefixes: []*KeyRule{
|
||||||
|
{
|
||||||
|
Prefix: "foo/priv/",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "bar/",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "zip/",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
},
|
||||||
PreparedQueries: []*PreparedQueryRule{
|
PreparedQueries: []*PreparedQueryRule{
|
||||||
{
|
{
|
||||||
Prefix: "bar",
|
Prefix: "bar",
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
PreparedQueryPrefixes: []*PreparedQueryRule{
|
||||||
|
{
|
||||||
|
Prefix: "bar",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
Services: []*ServiceRule{
|
Services: []*ServiceRule{
|
||||||
{
|
{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ServicePrefixes: []*ServiceRule{
|
||||||
|
{
|
||||||
|
Name: "bar",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "ServiceReadAllDenied", prefix: "", check: checkDenyServiceReadAll},
|
{name: "ServiceReadAllDenied", prefix: "", check: checkDenyServiceReadAll},
|
||||||
|
@ -2113,7 +2394,7 @@ func TestACL(t *testing.T) {
|
||||||
name: "ComplexDefaultAllow",
|
name: "ComplexDefaultAllow",
|
||||||
defaultPolicy: AllowAll(),
|
defaultPolicy: AllowAll(),
|
||||||
policyStack: []*Policy{
|
policyStack: []*Policy{
|
||||||
legacyPolicy(&Policy{
|
{
|
||||||
PolicyRules: PolicyRules{
|
PolicyRules: PolicyRules{
|
||||||
Events: []*EventRule{
|
Events: []*EventRule{
|
||||||
{
|
{
|
||||||
|
@ -2129,6 +2410,20 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyDeny,
|
Policy: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
EventPrefixes: []*EventRule{
|
||||||
|
{
|
||||||
|
Event: "",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: "foo",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: "bar",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
Keys: []*KeyRule{
|
Keys: []*KeyRule{
|
||||||
{
|
{
|
||||||
Prefix: "foo/",
|
Prefix: "foo/",
|
||||||
|
@ -2151,6 +2446,28 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyList,
|
Policy: PolicyList,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
KeyPrefixes: []*KeyRule{
|
||||||
|
{
|
||||||
|
Prefix: "foo/",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "foo/priv/",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "bar/",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "zip/",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "zap/",
|
||||||
|
Policy: PolicyList,
|
||||||
|
},
|
||||||
|
},
|
||||||
PreparedQueries: []*PreparedQueryRule{
|
PreparedQueries: []*PreparedQueryRule{
|
||||||
{
|
{
|
||||||
Prefix: "",
|
Prefix: "",
|
||||||
|
@ -2169,6 +2486,24 @@ func TestACL(t *testing.T) {
|
||||||
Policy: PolicyWrite,
|
Policy: PolicyWrite,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
PreparedQueryPrefixes: []*PreparedQueryRule{
|
||||||
|
{
|
||||||
|
Prefix: "",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "foo",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "bar",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Prefix: "zoo",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
},
|
||||||
Services: []*ServiceRule{
|
Services: []*ServiceRule{
|
||||||
{
|
{
|
||||||
Name: "",
|
Name: "",
|
||||||
|
@ -2193,8 +2528,32 @@ func TestACL(t *testing.T) {
|
||||||
Intentions: PolicyDeny,
|
Intentions: PolicyDeny,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ServicePrefixes: []*ServiceRule{
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Policy: PolicyRead,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "bar",
|
||||||
|
Policy: PolicyDeny,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "barfoo",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
Intentions: PolicyWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "intbaz",
|
||||||
|
Policy: PolicyWrite,
|
||||||
|
Intentions: PolicyDeny,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
checks: []aclCheck{
|
checks: []aclCheck{
|
||||||
{name: "ServiceReadAllDenied", prefix: "", check: checkDenyServiceReadAll},
|
{name: "ServiceReadAllDenied", prefix: "", check: checkDenyServiceReadAll},
|
||||||
|
@ -2905,7 +3264,7 @@ func TestACL_ReadAll(t *testing.T) {
|
||||||
body := func(t *testing.T, rules string, defaultPolicy Authorizer, check func(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext)) {
|
body := func(t *testing.T, rules string, defaultPolicy Authorizer, check func(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext)) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
policy, err := NewPolicyFromSource(rules, SyntaxCurrent, nil, nil)
|
policy, err := NewPolicyFromSource(rules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
acl, err := NewPolicyAuthorizerWithDefaults(defaultPolicy, []*Policy{policy}, nil)
|
acl, err := NewPolicyAuthorizerWithDefaults(defaultPolicy, []*Policy{policy}, nil)
|
||||||
|
|
|
@ -586,9 +586,8 @@ func Enforce(authz Authorizer, rsc Resource, segment string, access string, ctx
|
||||||
|
|
||||||
// NewAuthorizerFromRules is a convenience function to invoke NewPolicyFromSource followed by NewPolicyAuthorizer with
|
// NewAuthorizerFromRules is a convenience function to invoke NewPolicyFromSource followed by NewPolicyAuthorizer with
|
||||||
// the parse policy.
|
// the parse policy.
|
||||||
// TODO(ACL-Legacy-Compat): remove syntax arg after removing SyntaxLegacy
|
func NewAuthorizerFromRules(rules string, conf *Config, meta *EnterprisePolicyMeta) (Authorizer, error) {
|
||||||
func NewAuthorizerFromRules(rules string, syntax SyntaxVersion, conf *Config, meta *EnterprisePolicyMeta) (Authorizer, error) {
|
policy, err := NewPolicyFromSource(rules, conf, meta)
|
||||||
policy, err := NewPolicyFromSource(rules, syntax, conf, meta)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
190
acl/policy.go
190
acl/policy.go
|
@ -1,15 +1,8 @@
|
||||||
package acl
|
package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl"
|
|
||||||
"github.com/hashicorp/hcl/hcl/ast"
|
|
||||||
hclprinter "github.com/hashicorp/hcl/hcl/printer"
|
|
||||||
"github.com/hashicorp/hcl/hcl/token"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SyntaxVersion int
|
type SyntaxVersion int
|
||||||
|
@ -297,7 +290,7 @@ func (pr *PolicyRules) Validate(conf *Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCurrent(rules string, conf *Config, meta *EnterprisePolicyMeta) (*Policy, error) {
|
func parse(rules string, conf *Config, meta *EnterprisePolicyMeta) (*Policy, error) {
|
||||||
p, err := decodeRules(rules, conf, meta)
|
p, err := decodeRules(rules, conf, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -314,126 +307,10 @@ func parseCurrent(rules string, conf *Config, meta *EnterprisePolicyMeta) (*Poli
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ACL-Legacy-Compat): remove in phase 2
|
|
||||||
func parseLegacy(rules string, conf *Config) (*Policy, error) {
|
|
||||||
p := &Policy{}
|
|
||||||
|
|
||||||
type LegacyPolicy struct {
|
|
||||||
Agents []*AgentRule `hcl:"agent,expand"`
|
|
||||||
Keys []*KeyRule `hcl:"key,expand"`
|
|
||||||
Nodes []*NodeRule `hcl:"node,expand"`
|
|
||||||
Services []*ServiceRule `hcl:"service,expand"`
|
|
||||||
Sessions []*SessionRule `hcl:"session,expand"`
|
|
||||||
Events []*EventRule `hcl:"event,expand"`
|
|
||||||
PreparedQueries []*PreparedQueryRule `hcl:"query,expand"`
|
|
||||||
Keyring string `hcl:"keyring"`
|
|
||||||
Operator string `hcl:"operator"`
|
|
||||||
// NOTE: mesh resources not supported here
|
|
||||||
}
|
|
||||||
|
|
||||||
lp := &LegacyPolicy{}
|
|
||||||
|
|
||||||
if err := hcl.Decode(lp, rules); err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to parse ACL rules: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the agent policy
|
|
||||||
for _, ap := range lp.Agents {
|
|
||||||
if !isPolicyValid(ap.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid agent policy: %#v", ap)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.AgentPrefixes = append(p.AgentPrefixes, ap)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the key policy
|
|
||||||
for _, kp := range lp.Keys {
|
|
||||||
if !isPolicyValid(kp.Policy, true) {
|
|
||||||
return nil, fmt.Errorf("Invalid key policy: %#v", kp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := kp.EnterpriseRule.Validate(kp.Policy, conf); err != nil {
|
|
||||||
return nil, fmt.Errorf("Invalid key enterprise policy: %#v, got error: %v", kp, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.KeyPrefixes = append(p.KeyPrefixes, kp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the node policies
|
|
||||||
for _, np := range lp.Nodes {
|
|
||||||
if !isPolicyValid(np.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid node policy: %#v", np)
|
|
||||||
}
|
|
||||||
if err := np.EnterpriseRule.Validate(np.Policy, conf); err != nil {
|
|
||||||
return nil, fmt.Errorf("Invalid node enterprise policy: %#v, got error: %v", np, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.NodePrefixes = append(p.NodePrefixes, np)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the service policies
|
|
||||||
for _, sp := range lp.Services {
|
|
||||||
if !isPolicyValid(sp.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid service policy: %#v", sp)
|
|
||||||
}
|
|
||||||
if sp.Intentions != "" && !isPolicyValid(sp.Intentions, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid service intentions policy: %#v", sp)
|
|
||||||
}
|
|
||||||
if err := sp.EnterpriseRule.Validate(sp.Policy, conf); err != nil {
|
|
||||||
return nil, fmt.Errorf("Invalid service enterprise policy: %#v, got error: %v", sp, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.ServicePrefixes = append(p.ServicePrefixes, sp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the session policies
|
|
||||||
for _, sp := range lp.Sessions {
|
|
||||||
if !isPolicyValid(sp.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid session policy: %#v", sp)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.SessionPrefixes = append(p.SessionPrefixes, sp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the user event policies
|
|
||||||
for _, ep := range lp.Events {
|
|
||||||
if !isPolicyValid(ep.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid event policy: %#v", ep)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.EventPrefixes = append(p.EventPrefixes, ep)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the prepared query policies
|
|
||||||
for _, pq := range lp.PreparedQueries {
|
|
||||||
if !isPolicyValid(pq.Policy, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid query policy: %#v", pq)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.PreparedQueryPrefixes = append(p.PreparedQueryPrefixes, pq)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the keyring policy - this one is allowed to be empty
|
|
||||||
if lp.Keyring != "" && !isPolicyValid(lp.Keyring, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid keyring policy: %#v", lp.Keyring)
|
|
||||||
} else {
|
|
||||||
p.Keyring = lp.Keyring
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the operator policy - this one is allowed to be empty
|
|
||||||
if lp.Operator != "" && !isPolicyValid(lp.Operator, false) {
|
|
||||||
return nil, fmt.Errorf("Invalid operator policy: %#v", lp.Operator)
|
|
||||||
} else {
|
|
||||||
p.Operator = lp.Operator
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPolicyFromSource is used to parse the specified ACL rules into an
|
// NewPolicyFromSource is used to parse the specified ACL rules into an
|
||||||
// intermediary set of policies, before being compiled into
|
// intermediary set of policies, before being compiled into
|
||||||
// the ACL
|
// the ACL
|
||||||
func NewPolicyFromSource(rules string, syntax SyntaxVersion, conf *Config, meta *EnterprisePolicyMeta) (*Policy, error) {
|
func NewPolicyFromSource(rules string, conf *Config, meta *EnterprisePolicyMeta) (*Policy, error) {
|
||||||
if rules == "" {
|
if rules == "" {
|
||||||
// Hot path for empty source
|
// Hot path for empty source
|
||||||
return &Policy{}, nil
|
return &Policy{}, nil
|
||||||
|
@ -441,15 +318,7 @@ func NewPolicyFromSource(rules string, syntax SyntaxVersion, conf *Config, meta
|
||||||
|
|
||||||
var policy *Policy
|
var policy *Policy
|
||||||
var err error
|
var err error
|
||||||
switch syntax {
|
policy, err = parse(rules, conf, meta)
|
||||||
// TODO(ACL-Legacy-Compat): remove and remove as argument from function
|
|
||||||
case SyntaxLegacy:
|
|
||||||
policy, err = parseLegacy(rules, conf)
|
|
||||||
case SyntaxCurrent:
|
|
||||||
policy, err = parseCurrent(rules, conf, meta)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("Invalid rules version: %d", syntax)
|
|
||||||
}
|
|
||||||
return policy, err
|
return policy, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,56 +351,3 @@ func takesPrecedenceOver(a, b string) bool {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func TranslateLegacyRules(policyBytes []byte) ([]byte, error) {
|
|
||||||
parsed, err := hcl.ParseBytes(policyBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to parse rules: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rewritten := ast.Walk(parsed, func(node ast.Node) (ast.Node, bool) {
|
|
||||||
switch n := node.(type) {
|
|
||||||
case *ast.ObjectItem:
|
|
||||||
if len(n.Keys) < 1 {
|
|
||||||
return node, true
|
|
||||||
}
|
|
||||||
|
|
||||||
txt := n.Keys[0].Token.Text
|
|
||||||
if n.Keys[0].Token.Type == token.STRING {
|
|
||||||
txt, err = strconv.Unquote(txt)
|
|
||||||
if err != nil {
|
|
||||||
return node, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch txt {
|
|
||||||
case "policy":
|
|
||||||
n.Keys[0].Token.Text = "policy"
|
|
||||||
case "agent":
|
|
||||||
n.Keys[0].Token.Text = "agent_prefix"
|
|
||||||
case "key":
|
|
||||||
n.Keys[0].Token.Text = "key_prefix"
|
|
||||||
case "node":
|
|
||||||
n.Keys[0].Token.Text = "node_prefix"
|
|
||||||
case "query":
|
|
||||||
n.Keys[0].Token.Text = "query_prefix"
|
|
||||||
case "service":
|
|
||||||
n.Keys[0].Token.Text = "service_prefix"
|
|
||||||
case "session":
|
|
||||||
n.Keys[0].Token.Text = "session_prefix"
|
|
||||||
case "event":
|
|
||||||
n.Keys[0].Token.Text = "event_prefix"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return node, true
|
|
||||||
})
|
|
||||||
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
|
|
||||||
if err := hclprinter.Fprint(buffer, rewritten); err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to output new rules: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ func errStartsWith(t *testing.T, actual error, expected string) {
|
||||||
func TestPolicySourceParse(t *testing.T) {
|
func TestPolicySourceParse(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Name string
|
Name string
|
||||||
Syntax SyntaxVersion
|
|
||||||
Rules string
|
Rules string
|
||||||
RulesJSON string
|
RulesJSON string
|
||||||
Expected *Policy
|
Expected *Policy
|
||||||
|
@ -24,7 +23,6 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "Basic",
|
Name: "Basic",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `
|
Rules: `
|
||||||
agent_prefix "bar" {
|
agent_prefix "bar" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
|
@ -302,291 +300,8 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "Legacy Basic",
|
|
||||||
Syntax: SyntaxLegacy,
|
|
||||||
Rules: `
|
|
||||||
agent "foo" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
agent "bar" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
event "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
event "foo" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
event "bar" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
key "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
key "foo/" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
key "foo/bar/" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
key "foo/bar/baz" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
keyring = "deny"
|
|
||||||
node "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
node "foo" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
node "bar" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
operator = "deny"
|
|
||||||
service "" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
service "foo" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
session "foo" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
session "bar" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
session "baz" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
query "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
query "foo" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
query "bar" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
RulesJSON: `
|
|
||||||
{
|
|
||||||
"agent": {
|
|
||||||
"foo": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"policy": "write"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"event": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"foo": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"foo/": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"foo/bar/": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"foo/bar/baz": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"keyring": "deny",
|
|
||||||
"node": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"foo": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"operator": "deny",
|
|
||||||
"service": {
|
|
||||||
"": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"foo": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"session": {
|
|
||||||
"foo": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"policy": "deny"
|
|
||||||
},
|
|
||||||
"baz": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"foo": {
|
|
||||||
"policy": "write"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{
|
|
||||||
AgentPrefixes: []*AgentRule{
|
|
||||||
{
|
|
||||||
Node: "foo",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Node: "bar",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
EventPrefixes: []*EventRule{
|
|
||||||
{
|
|
||||||
Event: "",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Event: "foo",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Event: "bar",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Keyring: PolicyDeny,
|
|
||||||
KeyPrefixes: []*KeyRule{
|
|
||||||
{
|
|
||||||
Prefix: "",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Prefix: "foo/",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Prefix: "foo/bar/",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Prefix: "foo/bar/baz",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
NodePrefixes: []*NodeRule{
|
|
||||||
{
|
|
||||||
Name: "",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "bar",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Operator: PolicyDeny,
|
|
||||||
PreparedQueryPrefixes: []*PreparedQueryRule{
|
|
||||||
{
|
|
||||||
Prefix: "",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Prefix: "foo",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Prefix: "bar",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ServicePrefixes: []*ServiceRule{
|
|
||||||
{
|
|
||||||
Name: "",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Policy: PolicyRead,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SessionPrefixes: []*SessionRule{
|
|
||||||
{
|
|
||||||
Node: "foo",
|
|
||||||
Policy: PolicyWrite,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Node: "bar",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Node: "baz",
|
|
||||||
Policy: PolicyDeny,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Service No Intentions (Legacy)",
|
|
||||||
Syntax: SyntaxLegacy,
|
|
||||||
Rules: `service "foo" { policy = "write" }`,
|
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write" }}}`,
|
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{
|
|
||||||
ServicePrefixes: []*ServiceRule{
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Policy: "write",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Service Intentions (Legacy)",
|
|
||||||
Syntax: SyntaxLegacy,
|
|
||||||
Rules: `service "foo" { policy = "write" intentions = "read" }`,
|
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "read" }}}`,
|
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{
|
|
||||||
ServicePrefixes: []*ServiceRule{
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Policy: "write",
|
|
||||||
Intentions: "read",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Service Intention: invalid value (Legacy)",
|
|
||||||
Syntax: SyntaxLegacy,
|
|
||||||
Rules: `service "foo" { policy = "write" intentions = "foo" }`,
|
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "foo" }}}`,
|
|
||||||
Err: "Invalid service intentions policy",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "Service No Intentions",
|
Name: "Service No Intentions",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `service "foo" { policy = "write" }`,
|
Rules: `service "foo" { policy = "write" }`,
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write" }}}`,
|
RulesJSON: `{ "service": { "foo": { "policy": "write" }}}`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{
|
Expected: &Policy{PolicyRules: PolicyRules{
|
||||||
|
@ -600,7 +315,6 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Service Intentions",
|
Name: "Service Intentions",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `service "foo" { policy = "write" intentions = "read" }`,
|
Rules: `service "foo" { policy = "write" intentions = "read" }`,
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "read" }}}`,
|
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "read" }}}`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{
|
Expected: &Policy{PolicyRules: PolicyRules{
|
||||||
|
@ -615,168 +329,144 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Service Intention: invalid value",
|
Name: "Service Intention: invalid value",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `service "foo" { policy = "write" intentions = "foo" }`,
|
Rules: `service "foo" { policy = "write" intentions = "foo" }`,
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "foo" }}}`,
|
RulesJSON: `{ "service": { "foo": { "policy": "write", "intentions": "foo" }}}`,
|
||||||
Err: "Invalid service intentions policy",
|
Err: "Invalid service intentions policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - ACL",
|
Name: "Bad Policy - ACL",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `acl = "list"`, // there is no list policy but this helps to exercise another check in isPolicyValid
|
Rules: `acl = "list"`, // there is no list policy but this helps to exercise another check in isPolicyValid
|
||||||
RulesJSON: `{ "acl": "list" }`, // there is no list policy but this helps to exercise another check in isPolicyValid
|
RulesJSON: `{ "acl": "list" }`, // there is no list policy but this helps to exercise another check in isPolicyValid
|
||||||
Err: "Invalid acl policy",
|
Err: "Invalid acl policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Agent",
|
Name: "Bad Policy - Agent",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `agent "foo" { policy = "nope" }`,
|
Rules: `agent "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "agent": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "agent": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid agent policy",
|
Err: "Invalid agent policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Agent Prefix",
|
Name: "Bad Policy - Agent Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `agent_prefix "foo" { policy = "nope" }`,
|
Rules: `agent_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "agent_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "agent_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid agent_prefix policy",
|
Err: "Invalid agent_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Key",
|
Name: "Bad Policy - Key",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `key "foo" { policy = "nope" }`,
|
Rules: `key "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "key": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "key": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid key policy",
|
Err: "Invalid key policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Key Prefix",
|
Name: "Bad Policy - Key Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `key_prefix "foo" { policy = "nope" }`,
|
Rules: `key_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "key_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "key_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid key_prefix policy",
|
Err: "Invalid key_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Node",
|
Name: "Bad Policy - Node",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `node "foo" { policy = "nope" }`,
|
Rules: `node "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "node": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "node": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid node policy",
|
Err: "Invalid node policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Node Prefix",
|
Name: "Bad Policy - Node Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `node_prefix "foo" { policy = "nope" }`,
|
Rules: `node_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "node_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "node_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid node_prefix policy",
|
Err: "Invalid node_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Service",
|
Name: "Bad Policy - Service",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `service "foo" { policy = "nope" }`,
|
Rules: `service "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "service": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "service": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid service policy",
|
Err: "Invalid service policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Service Prefix",
|
Name: "Bad Policy - Service Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `service_prefix "foo" { policy = "nope" }`,
|
Rules: `service_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "service_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "service_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid service_prefix policy",
|
Err: "Invalid service_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Session",
|
Name: "Bad Policy - Session",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `session "foo" { policy = "nope" }`,
|
Rules: `session "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "session": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "session": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid session policy",
|
Err: "Invalid session policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Session Prefix",
|
Name: "Bad Policy - Session Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `session_prefix "foo" { policy = "nope" }`,
|
Rules: `session_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "session_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "session_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid session_prefix policy",
|
Err: "Invalid session_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Event",
|
Name: "Bad Policy - Event",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `event "foo" { policy = "nope" }`,
|
Rules: `event "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "event": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "event": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid event policy",
|
Err: "Invalid event policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Event Prefix",
|
Name: "Bad Policy - Event Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `event_prefix "foo" { policy = "nope" }`,
|
Rules: `event_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "event_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "event_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid event_prefix policy",
|
Err: "Invalid event_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Prepared Query",
|
Name: "Bad Policy - Prepared Query",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `query "foo" { policy = "nope" }`,
|
Rules: `query "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "query": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "query": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid query policy",
|
Err: "Invalid query policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Prepared Query Prefix",
|
Name: "Bad Policy - Prepared Query Prefix",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `query_prefix "foo" { policy = "nope" }`,
|
Rules: `query_prefix "foo" { policy = "nope" }`,
|
||||||
RulesJSON: `{ "query_prefix": { "foo": { "policy": "nope" }}}`,
|
RulesJSON: `{ "query_prefix": { "foo": { "policy": "nope" }}}`,
|
||||||
Err: "Invalid query_prefix policy",
|
Err: "Invalid query_prefix policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Keyring",
|
Name: "Bad Policy - Keyring",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `keyring = "nope"`,
|
Rules: `keyring = "nope"`,
|
||||||
RulesJSON: `{ "keyring": "nope" }`,
|
RulesJSON: `{ "keyring": "nope" }`,
|
||||||
Err: "Invalid keyring policy",
|
Err: "Invalid keyring policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Operator",
|
Name: "Bad Policy - Operator",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `operator = "nope"`,
|
Rules: `operator = "nope"`,
|
||||||
RulesJSON: `{ "operator": "nope" }`,
|
RulesJSON: `{ "operator": "nope" }`,
|
||||||
Err: "Invalid operator policy",
|
Err: "Invalid operator policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Mesh",
|
Name: "Bad Policy - Mesh",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `mesh = "nope"`,
|
Rules: `mesh = "nope"`,
|
||||||
RulesJSON: `{ "mesh": "nope" }`,
|
RulesJSON: `{ "mesh": "nope" }`,
|
||||||
Err: "Invalid mesh policy",
|
Err: "Invalid mesh policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Bad Policy - Peering",
|
Name: "Bad Policy - Peering",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `peering = "nope"`,
|
Rules: `peering = "nope"`,
|
||||||
RulesJSON: `{ "peering": "nope" }`,
|
RulesJSON: `{ "peering": "nope" }`,
|
||||||
Err: "Invalid peering policy",
|
Err: "Invalid peering policy",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Keyring Empty",
|
Name: "Keyring Empty",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `keyring = ""`,
|
Rules: `keyring = ""`,
|
||||||
RulesJSON: `{ "keyring": "" }`,
|
RulesJSON: `{ "keyring": "" }`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{Keyring: ""}},
|
Expected: &Policy{PolicyRules: PolicyRules{Keyring: ""}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Operator Empty",
|
Name: "Operator Empty",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `operator = ""`,
|
Rules: `operator = ""`,
|
||||||
RulesJSON: `{ "operator": "" }`,
|
RulesJSON: `{ "operator": "" }`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{Operator: ""}},
|
Expected: &Policy{PolicyRules: PolicyRules{Operator: ""}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Mesh Empty",
|
Name: "Mesh Empty",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `mesh = ""`,
|
Rules: `mesh = ""`,
|
||||||
RulesJSON: `{ "mesh": "" }`,
|
RulesJSON: `{ "mesh": "" }`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{Mesh: ""}},
|
Expected: &Policy{PolicyRules: PolicyRules{Mesh: ""}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Peering Empty",
|
Name: "Peering Empty",
|
||||||
Syntax: SyntaxCurrent,
|
|
||||||
Rules: `peering = ""`,
|
Rules: `peering = ""`,
|
||||||
RulesJSON: `{ "peering": "" }`,
|
RulesJSON: `{ "peering": "" }`,
|
||||||
Expected: &Policy{PolicyRules: PolicyRules{Peering: ""}},
|
Expected: &Policy{PolicyRules: PolicyRules{Peering: ""}},
|
||||||
|
@ -788,7 +478,7 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
require.True(t, tc.Rules != "" || tc.RulesJSON != "")
|
require.True(t, tc.Rules != "" || tc.RulesJSON != "")
|
||||||
if tc.Rules != "" {
|
if tc.Rules != "" {
|
||||||
t.Run("hcl", func(t *testing.T) {
|
t.Run("hcl", func(t *testing.T) {
|
||||||
actual, err := NewPolicyFromSource(tc.Rules, tc.Syntax, nil, nil)
|
actual, err := NewPolicyFromSource(tc.Rules, nil, nil)
|
||||||
if tc.Err != "" {
|
if tc.Err != "" {
|
||||||
errStartsWith(t, err, tc.Err)
|
errStartsWith(t, err, tc.Err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -798,7 +488,7 @@ func TestPolicySourceParse(t *testing.T) {
|
||||||
}
|
}
|
||||||
if tc.RulesJSON != "" {
|
if tc.RulesJSON != "" {
|
||||||
t.Run("json", func(t *testing.T) {
|
t.Run("json", func(t *testing.T) {
|
||||||
actual, err := NewPolicyFromSource(tc.RulesJSON, tc.Syntax, nil, nil)
|
actual, err := NewPolicyFromSource(tc.RulesJSON, nil, nil)
|
||||||
if tc.Err != "" {
|
if tc.Err != "" {
|
||||||
errStartsWith(t, err, tc.Err)
|
errStartsWith(t, err, tc.Err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1585,236 +1275,6 @@ func TestMergePolicies(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRulesTranslate(t *testing.T) {
|
|
||||||
input := `
|
|
||||||
# top level comment
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
agent "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
key "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
node "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
event "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
service "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
session "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
query "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# comment
|
|
||||||
keyring = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
operator = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
mesh = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
peering = "write"
|
|
||||||
`
|
|
||||||
|
|
||||||
expected := `
|
|
||||||
# top level comment
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
agent_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
key_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
node_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
event_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
service_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
session_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# block comment
|
|
||||||
query_prefix "" {
|
|
||||||
# policy comment
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
# comment
|
|
||||||
keyring = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
operator = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
mesh = "write"
|
|
||||||
|
|
||||||
# comment
|
|
||||||
peering = "write"
|
|
||||||
`
|
|
||||||
|
|
||||||
output, err := TranslateLegacyRules([]byte(input))
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, strings.Trim(expected, "\n"), string(output))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRulesTranslate_GH5493(t *testing.T) {
|
|
||||||
input := `
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"policy": {
|
|
||||||
"policy": "read"
|
|
||||||
},
|
|
||||||
"privatething1/": {
|
|
||||||
"policy": "deny"
|
|
||||||
},
|
|
||||||
"anapplication/private/": {
|
|
||||||
"policy": "deny"
|
|
||||||
},
|
|
||||||
"privatething2/": {
|
|
||||||
"policy": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"session": {
|
|
||||||
"": {
|
|
||||||
"policy": "write"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"agent": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"event": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": {
|
|
||||||
"": {
|
|
||||||
"policy": "read"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
expected := `
|
|
||||||
key_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
key_prefix "key" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
key_prefix "policy" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
key_prefix "privatething1/" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
|
|
||||||
key_prefix "anapplication/private/" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
|
|
||||||
key_prefix "privatething2/" {
|
|
||||||
policy = "deny"
|
|
||||||
}
|
|
||||||
|
|
||||||
session_prefix "" {
|
|
||||||
policy = "write"
|
|
||||||
}
|
|
||||||
|
|
||||||
node_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
agent_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
service_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
event_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
|
|
||||||
query_prefix "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
output, err := TranslateLegacyRules([]byte(input))
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, strings.Trim(expected, "\n"), string(output))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrecedence(t *testing.T) {
|
func TestPrecedence(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -215,8 +215,6 @@ func (s *HTTPHandlers) aclPolicyWriteInternal(_resp http.ResponseWriter, req *ht
|
||||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Policy decoding failed: %v", err)}
|
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Policy decoding failed: %v", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Policy.Syntax = acl.SyntaxCurrent
|
|
||||||
|
|
||||||
if create {
|
if create {
|
||||||
if args.Policy.ID != "" {
|
if args.Policy.ID != "" {
|
||||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Cannot specify the ID when creating a new policy"}
|
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Cannot specify the ID when creating a new policy"}
|
||||||
|
@ -1009,10 +1007,9 @@ func (s *HTTPHandlers) ACLAuthorize(resp http.ResponseWriter, req *http.Request)
|
||||||
// There are a number of reason why this is okay.
|
// There are a number of reason why this is okay.
|
||||||
//
|
//
|
||||||
// 1. The authorizations performed here are the same as what would be done if other HTTP APIs
|
// 1. The authorizations performed here are the same as what would be done if other HTTP APIs
|
||||||
// were used. This is just a way to see if it would be allowed. In the future when we have
|
// were used. This is just a way to see if it would be allowed. These authorization checks
|
||||||
// audit logging, these authorization checks will be logged along with those from the real
|
// will be logged along with those from the real endpoints. In that respect, you can figure
|
||||||
// endpoints. In that respect, you can figure out if you have access just as easily by
|
// out if you have access just as easily by attempting to perform the requested operation.
|
||||||
// attempting to perform the requested operation.
|
|
||||||
// 2. In order to use this API you must have a valid ACL token secret.
|
// 2. In order to use this API you must have a valid ACL token secret.
|
||||||
// 3. Along with #2 you can use the ACL.GetPolicy RPC endpoint which will return a rolled up
|
// 3. Along with #2 you can use the ACL.GetPolicy RPC endpoint which will return a rolled up
|
||||||
// set of policy rules showing your tokens effective policy. This RPC endpoint exposes
|
// set of policy rules showing your tokens effective policy. This RPC endpoint exposes
|
||||||
|
|
|
@ -238,7 +238,7 @@ func catalogPolicy(testACL string) (structs.ACLIdentity, acl.Authorizer, error)
|
||||||
return nil, nil, acl.ErrNotFound
|
return nil, nil, acl.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
policy, err := acl.NewPolicyFromSource(tok.rules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tok.rules, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,7 +535,7 @@ func TestAgent_Service(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
tokenRules string
|
policies string
|
||||||
url string
|
url string
|
||||||
updateFunc func()
|
updateFunc func()
|
||||||
wantWait time.Duration
|
wantWait time.Duration
|
||||||
|
@ -671,7 +671,7 @@ func TestAgent_Service(t *testing.T) {
|
||||||
name: "err: bad ACL for service",
|
name: "err: bad ACL for service",
|
||||||
url: "/v1/agent/service/web-sidecar-proxy",
|
url: "/v1/agent/service/web-sidecar-proxy",
|
||||||
// Limited token doesn't grant read to the service
|
// Limited token doesn't grant read to the service
|
||||||
tokenRules: `
|
policies: `
|
||||||
key "" {
|
key "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ func TestAgent_Service(t *testing.T) {
|
||||||
name: "good ACL for service",
|
name: "good ACL for service",
|
||||||
url: "/v1/agent/service/web-sidecar-proxy",
|
url: "/v1/agent/service/web-sidecar-proxy",
|
||||||
// Limited token doesn't grant read to the service
|
// Limited token doesn't grant read to the service
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
|
@ -711,9 +711,9 @@ func TestAgent_Service(t *testing.T) {
|
||||||
|
|
||||||
// Inject the root token for tests that don't care about ACL
|
// Inject the root token for tests that don't care about ACL
|
||||||
token := "root"
|
token := "root"
|
||||||
if tt.tokenRules != "" {
|
if tt.policies != "" {
|
||||||
// Create new token and use that.
|
// Create new token and use that.
|
||||||
token = testCreateToken(t, a, tt.tokenRules)
|
token = testCreateToken(t, a, tt.policies)
|
||||||
}
|
}
|
||||||
req.Header.Set("X-Consul-Token", token)
|
req.Header.Set("X-Consul-Token", token)
|
||||||
resp := httptest.NewRecorder()
|
resp := httptest.NewRecorder()
|
||||||
|
@ -4353,7 +4353,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
// directly.
|
// directly.
|
||||||
json string
|
json string
|
||||||
enableACL bool
|
enableACL bool
|
||||||
tokenRules string
|
policies string
|
||||||
wantNS *structs.NodeService
|
wantNS *structs.NodeService
|
||||||
wantErr string
|
wantErr string
|
||||||
wantSidecarIDLeftAfterDereg bool
|
wantSidecarIDLeftAfterDereg bool
|
||||||
|
@ -4396,7 +4396,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4418,7 +4418,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: ``, // No token rules means no valid token
|
policies: ``, // No token rules means no valid token
|
||||||
wantNS: nil,
|
wantNS: nil,
|
||||||
wantErr: "Permission denied",
|
wantErr: "Permission denied",
|
||||||
},
|
},
|
||||||
|
@ -4435,7 +4435,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
// This will become more common/reasonable when ACLs support exact match.
|
// This will become more common/reasonable when ACLs support exact match.
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "deny"
|
policy = "deny"
|
||||||
}
|
}
|
||||||
|
@ -4461,7 +4461,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4485,7 +4485,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4514,7 +4514,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4739,8 +4739,8 @@ func testAgent_RegisterServiceDeregisterService_Sidecar(t *testing.T, extraHCL s
|
||||||
|
|
||||||
// Create an ACL token with require policy
|
// Create an ACL token with require policy
|
||||||
var token string
|
var token string
|
||||||
if tt.enableACL && tt.tokenRules != "" {
|
if tt.enableACL && tt.policies != "" {
|
||||||
token = testCreateToken(t, a, tt.tokenRules)
|
token = testCreateToken(t, a, tt.policies)
|
||||||
}
|
}
|
||||||
|
|
||||||
br := bytes.NewBufferString(tt.json)
|
br := bytes.NewBufferString(tt.json)
|
||||||
|
@ -4850,7 +4850,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
// directly.
|
// directly.
|
||||||
json string
|
json string
|
||||||
enableACL bool
|
enableACL bool
|
||||||
tokenRules string
|
policies string
|
||||||
wantNS *structs.NodeService
|
wantNS *structs.NodeService
|
||||||
wantErr string
|
wantErr string
|
||||||
wantSidecarIDLeftAfterDereg bool
|
wantSidecarIDLeftAfterDereg bool
|
||||||
|
@ -4893,7 +4893,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4915,7 +4915,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: ``, // No token rules means no valid token
|
policies: ``, // No policies means no valid token
|
||||||
wantNS: nil,
|
wantNS: nil,
|
||||||
wantErr: "Permission denied",
|
wantErr: "Permission denied",
|
||||||
},
|
},
|
||||||
|
@ -4932,7 +4932,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
// This will become more common/reasonable when ACLs support exact match.
|
// This will become more common/reasonable when ACLs support exact match.
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "deny"
|
policy = "deny"
|
||||||
}
|
}
|
||||||
|
@ -4958,7 +4958,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -4982,7 +4982,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -5011,7 +5011,7 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
enableACL: true,
|
enableACL: true,
|
||||||
tokenRules: `
|
policies: `
|
||||||
service "web-sidecar-proxy" {
|
service "web-sidecar-proxy" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
|
@ -5236,8 +5236,8 @@ func testAgent_RegisterServiceDeregisterService_Sidecar_UDP(t *testing.T, extraH
|
||||||
|
|
||||||
// Create an ACL token with require policy
|
// Create an ACL token with require policy
|
||||||
var token string
|
var token string
|
||||||
if tt.enableACL && tt.tokenRules != "" {
|
if tt.enableACL && tt.policies != "" {
|
||||||
token = testCreateToken(t, a, tt.tokenRules)
|
token = testCreateToken(t, a, tt.policies)
|
||||||
}
|
}
|
||||||
|
|
||||||
br := bytes.NewBufferString(tt.json)
|
br := bytes.NewBufferString(tt.json)
|
||||||
|
|
|
@ -284,7 +284,7 @@ func agentRecoveryAuthorizer(nodeName string, entMeta *acl.EnterpriseMeta, aclCo
|
||||||
node_prefix "" {
|
node_prefix "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, nodeName), acl.SyntaxCurrent, &conf, entMeta.ToEnterprisePolicyMeta())
|
`, nodeName), &conf, entMeta.ToEnterprisePolicyMeta())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -913,7 +913,7 @@ func (a *ACL) PolicySet(args *structs.ACLPolicySetRequest, reply *structs.ACLPol
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the rules
|
// validate the rules
|
||||||
_, err = acl.NewPolicyFromSource(policy.Rules, policy.Syntax, a.srv.aclConfig, policy.EnterprisePolicyMeta())
|
_, err = acl.NewPolicyFromSource(policy.Rules, a.srv.aclConfig, policy.EnterprisePolicyMeta())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package consul
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LegacyACLGetPolicy struct{}
|
|
||||||
|
|
||||||
func (a *ACL) GetPolicy(*LegacyACLGetPolicy, *LegacyACLGetPolicy) error {
|
|
||||||
return fmt.Errorf("ACL.GetPolicy: the legacy ACL system has been removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACL) Bootstrap(*structs.DCSpecificRequest, *LegacyACLRequest) error {
|
|
||||||
return fmt.Errorf("ACL.Bootstrap: the legacy ACL system has been removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
type LegacyACLRequest struct{}
|
|
||||||
|
|
||||||
func (a *ACL) Apply(*LegacyACLRequest, *string) error {
|
|
||||||
return fmt.Errorf("ACL.Apply: the legacy ACL system has been removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACL) Get(*LegacyACLRequest, *LegacyACLRequest) error {
|
|
||||||
return fmt.Errorf("ACL.Get: the legacy ACL system has been removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ACL) List(*structs.DCSpecificRequest, *LegacyACLRequest) error {
|
|
||||||
return fmt.Errorf("ACL.List: the legacy ACL system has been removed")
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
|
||||||
"github.com/hashicorp/consul/agent/consul/authmethod/testauth"
|
"github.com/hashicorp/consul/agent/consul/authmethod/testauth"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
||||||
|
@ -31,7 +30,6 @@ func TestACLReplication_diffACLPolicies(t *testing.T) {
|
||||||
Name: "policy1",
|
Name: "policy1",
|
||||||
Description: "policy1 - already in sync",
|
Description: "policy1 - already in sync",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: nil,
|
Datacenters: nil,
|
||||||
Hash: []byte{1, 2, 3, 4},
|
Hash: []byte{1, 2, 3, 4},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
|
@ -41,7 +39,6 @@ func TestACLReplication_diffACLPolicies(t *testing.T) {
|
||||||
Name: "policy2",
|
Name: "policy2",
|
||||||
Description: "policy2 - updated but not changed",
|
Description: "policy2 - updated but not changed",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: nil,
|
Datacenters: nil,
|
||||||
Hash: []byte{1, 2, 3, 4},
|
Hash: []byte{1, 2, 3, 4},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
||||||
|
@ -51,7 +48,6 @@ func TestACLReplication_diffACLPolicies(t *testing.T) {
|
||||||
Name: "policy3",
|
Name: "policy3",
|
||||||
Description: "policy3 - updated and changed",
|
Description: "policy3 - updated and changed",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: nil,
|
Datacenters: nil,
|
||||||
Hash: []byte{1, 2, 3, 4},
|
Hash: []byte{1, 2, 3, 4},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
||||||
|
@ -61,7 +57,6 @@ func TestACLReplication_diffACLPolicies(t *testing.T) {
|
||||||
Name: "policy4",
|
Name: "policy4",
|
||||||
Description: "policy4 - needs deleting",
|
Description: "policy4 - needs deleting",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: nil,
|
Datacenters: nil,
|
||||||
Hash: []byte{1, 2, 3, 4},
|
Hash: []byte{1, 2, 3, 4},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 25},
|
||||||
|
|
|
@ -213,7 +213,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "acl-ro",
|
Name: "acl-ro",
|
||||||
Description: "acl-ro",
|
Description: "acl-ro",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
p.SetHash(false)
|
p.SetHash(false)
|
||||||
|
@ -224,7 +223,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "acl-wr",
|
Name: "acl-wr",
|
||||||
Description: "acl-wr",
|
Description: "acl-wr",
|
||||||
Rules: `acl = "write"`,
|
Rules: `acl = "write"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
p.SetHash(false)
|
p.SetHash(false)
|
||||||
|
@ -235,7 +233,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "service-ro",
|
Name: "service-ro",
|
||||||
Description: "service-ro",
|
Description: "service-ro",
|
||||||
Rules: `service_prefix "" { policy = "read" }`,
|
Rules: `service_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
p.SetHash(false)
|
p.SetHash(false)
|
||||||
|
@ -246,7 +243,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "service-wr",
|
Name: "service-wr",
|
||||||
Description: "service-wr",
|
Description: "service-wr",
|
||||||
Rules: `service_prefix "" { policy = "write" }`,
|
Rules: `service_prefix "" { policy = "write" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
p.SetHash(false)
|
p.SetHash(false)
|
||||||
|
@ -257,7 +253,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "node-wr",
|
Name: "node-wr",
|
||||||
Description: "node-wr",
|
Description: "node-wr",
|
||||||
Rules: `node_prefix "" { policy = "write"}`,
|
Rules: `node_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
|
@ -269,7 +264,6 @@ func testPolicyForID(policyID string) (bool, *structs.ACLPolicy, error) {
|
||||||
Name: "dc2-key-wr",
|
Name: "dc2-key-wr",
|
||||||
Description: "dc2-key-wr",
|
Description: "dc2-key-wr",
|
||||||
Rules: `key_prefix "" { policy = "write"}`,
|
Rules: `key_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc2"},
|
Datacenters: []string{"dc2"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1693,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "acl-ro",
|
Name: "acl-ro",
|
||||||
Description: "acl-ro",
|
Description: "acl-ro",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1733,7 +1726,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "acl-ro",
|
Name: "acl-ro",
|
||||||
Description: "acl-ro",
|
Description: "acl-ro",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1768,7 +1760,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "acl-ro",
|
Name: "acl-ro",
|
||||||
Description: "acl-ro",
|
Description: "acl-ro",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1793,7 +1784,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "node-wr",
|
Name: "node-wr",
|
||||||
Description: "node-wr",
|
Description: "node-wr",
|
||||||
Rules: `node_prefix "" { policy = "write"}`,
|
Rules: `node_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1802,7 +1792,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "dc2-key-wr",
|
Name: "dc2-key-wr",
|
||||||
Description: "dc2-key-wr",
|
Description: "dc2-key-wr",
|
||||||
Rules: `key_prefix "" { policy = "write"}`,
|
Rules: `key_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc2"},
|
Datacenters: []string{"dc2"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1836,7 +1825,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "node-wr",
|
Name: "node-wr",
|
||||||
Description: "node-wr",
|
Description: "node-wr",
|
||||||
Rules: `node_prefix "" { policy = "write"}`,
|
Rules: `node_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1845,7 +1833,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "dc2-key-wr",
|
Name: "dc2-key-wr",
|
||||||
Description: "dc2-key-wr",
|
Description: "dc2-key-wr",
|
||||||
Rules: `key_prefix "" { policy = "write"}`,
|
Rules: `key_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc2"},
|
Datacenters: []string{"dc2"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1874,7 +1861,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "node-wr",
|
Name: "node-wr",
|
||||||
Description: "node-wr",
|
Description: "node-wr",
|
||||||
Rules: `node_prefix "" { policy = "write"}`,
|
Rules: `node_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1883,7 +1869,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "dc2-key-wr",
|
Name: "dc2-key-wr",
|
||||||
Description: "dc2-key-wr",
|
Description: "dc2-key-wr",
|
||||||
Rules: `key_prefix "" { policy = "write"}`,
|
Rules: `key_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc2"},
|
Datacenters: []string{"dc2"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -1901,7 +1886,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "service-ro",
|
Name: "service-ro",
|
||||||
Description: "service-ro",
|
Description: "service-ro",
|
||||||
Rules: `service_prefix "" { policy = "read" }`,
|
Rules: `service_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2072,7 +2056,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "node-wr",
|
Name: "node-wr",
|
||||||
Description: "node-wr",
|
Description: "node-wr",
|
||||||
Rules: `node_prefix "" { policy = "write"}`,
|
Rules: `node_prefix "" { policy = "write"}`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
|
@ -2098,7 +2081,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega
|
||||||
Name: "ixn-write",
|
Name: "ixn-write",
|
||||||
Description: "ixn-write",
|
Description: "ixn-write",
|
||||||
Rules: `service_prefix "" { policy = "write" intentions = "write" }`,
|
Rules: `service_prefix "" { policy = "write" intentions = "write" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
RaftIndex: structs.RaftIndex{CreateIndex: 1, ModifyIndex: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -306,10 +306,6 @@ func (w *TokenWriter) write(token, existing *structs.ACLToken, fromLogin bool) (
|
||||||
}
|
}
|
||||||
token.NodeIdentities = nodeIdentities
|
token.NodeIdentities = nodeIdentities
|
||||||
|
|
||||||
if token.Type != "" {
|
|
||||||
return nil, errors.New("Type cannot be specified for this token")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := w.enterpriseValidation(token, existing); err != nil {
|
if err := w.enterpriseValidation(token, existing); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,10 +98,6 @@ func TestTokenWriter_Create_Validation(t *testing.T) {
|
||||||
fromLogin: false,
|
fromLogin: false,
|
||||||
errorContains: "AuthMethod field is disallowed outside of login",
|
errorContains: "AuthMethod field is disallowed outside of login",
|
||||||
},
|
},
|
||||||
"Type set": {
|
|
||||||
token: structs.ACLToken{Type: "some-type"},
|
|
||||||
errorContains: "Type cannot be specified for this token",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for desc, tc := range testCases {
|
for desc, tc := range testCases {
|
||||||
t.Run(desc, func(t *testing.T) {
|
t.Run(desc, func(t *testing.T) {
|
||||||
|
@ -494,10 +490,6 @@ func TestTokenWriter_Update_Validation(t *testing.T) {
|
||||||
token: structs.ACLToken{AccessorID: token.AccessorID, ExpirationTime: timePointer(token.ExpirationTime.Add(1 * time.Minute))},
|
token: structs.ACLToken{AccessorID: token.AccessorID, ExpirationTime: timePointer(token.ExpirationTime.Add(1 * time.Minute))},
|
||||||
errorContains: "Cannot change expiration time",
|
errorContains: "Cannot change expiration time",
|
||||||
},
|
},
|
||||||
"Type set": {
|
|
||||||
token: structs.ACLToken{AccessorID: token.AccessorID, Type: "some-type"},
|
|
||||||
errorContains: "Type cannot be specified for this token",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for desc, tc := range testCases {
|
for desc, tc := range testCases {
|
||||||
t.Run(desc, func(t *testing.T) {
|
t.Run(desc, func(t *testing.T) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ func TestEventPayloadReadyServers_HasReadPermission(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -3588,7 +3588,7 @@ service "gateway" {
|
||||||
|
|
||||||
func TestVetRegisterWithACL(t *testing.T) {
|
func TestVetRegisterWithACL(t *testing.T) {
|
||||||
appendAuthz := func(t *testing.T, defaultAuthz acl.Authorizer, rules string) acl.Authorizer {
|
appendAuthz := func(t *testing.T, defaultAuthz acl.Authorizer, rules string) acl.Authorizer {
|
||||||
policy, err := acl.NewPolicyFromSource(rules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(rules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(defaultAuthz, []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(defaultAuthz, []*acl.Policy{policy}, nil)
|
||||||
|
@ -3876,10 +3876,10 @@ func TestVetDeregisterWithACL(t *testing.T) {
|
||||||
|
|
||||||
// Create a basic node policy.
|
// Create a basic node policy.
|
||||||
policy, err := acl.NewPolicyFromSource(`
|
policy, err := acl.NewPolicyFromSource(`
|
||||||
node "node" {
|
node_prefix "node" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err %v", err)
|
t.Fatalf("err %v", err)
|
||||||
}
|
}
|
||||||
|
@ -3892,7 +3892,7 @@ node "node" {
|
||||||
service "my-service" {
|
service "my-service" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err %v", err)
|
t.Fatalf("err %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func TestFilter_DirEnt(t *testing.T) {
|
func TestFilter_DirEnt(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
policy, _ := acl.NewPolicyFromSource(testFilterRules, acl.SyntaxLegacy, nil, nil)
|
policy, _ := acl.NewPolicyFromSource(testFilterRules, nil, nil)
|
||||||
aclR, _ := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
aclR, _ := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
||||||
type tcase struct {
|
type tcase struct {
|
||||||
|
@ -52,7 +52,7 @@ func TestFilter_DirEnt(t *testing.T) {
|
||||||
|
|
||||||
func TestFilter_TxnResults(t *testing.T) {
|
func TestFilter_TxnResults(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
policy, _ := acl.NewPolicyFromSource(testFilterRules, acl.SyntaxLegacy, nil, nil)
|
policy, _ := acl.NewPolicyFromSource(testFilterRules, nil, nil)
|
||||||
aclR, _ := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
aclR, _ := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
||||||
type tcase struct {
|
type tcase struct {
|
||||||
|
@ -101,16 +101,16 @@ func TestFilter_TxnResults(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var testFilterRules = `
|
var testFilterRules = `
|
||||||
key "" {
|
key_prefix "" {
|
||||||
policy = "deny"
|
policy = "deny"
|
||||||
}
|
}
|
||||||
key "foo/" {
|
key_prefix "foo/" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
key "foo/priv/" {
|
key_prefix "foo/priv/" {
|
||||||
policy = "deny"
|
policy = "deny"
|
||||||
}
|
}
|
||||||
key "zip/" {
|
key_prefix "zip/" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
@ -113,7 +113,6 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
|
||||||
},
|
},
|
||||||
CreateTime: time.Now(),
|
CreateTime: time.Now(),
|
||||||
Local: false,
|
Local: false,
|
||||||
Type: "management",
|
|
||||||
}
|
}
|
||||||
require.NoError(t, fsm.state.ACLBootstrap(10, 0, token))
|
require.NoError(t, fsm.state.ACLBootstrap(10, 0, token))
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,6 @@ func (s *Server) initializeACLs(ctx context.Context) error {
|
||||||
Name: "global-management",
|
Name: "global-management",
|
||||||
Description: "Builtin Policy that grants unlimited access",
|
Description: "Builtin Policy that grants unlimited access",
|
||||||
Rules: structs.ACLPolicyGlobalManagement,
|
Rules: structs.ACLPolicyGlobalManagement,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
||||||
}
|
}
|
||||||
if policy != nil {
|
if policy != nil {
|
||||||
|
|
|
@ -450,13 +450,13 @@ func aclTokenSetTxn(tx WriteTxn, idx uint64, token *structs.ACLToken, opts ACLTo
|
||||||
if token.AccessorID == "" {
|
if token.AccessorID == "" {
|
||||||
return ErrMissingACLTokenAccessor
|
return ErrMissingACLTokenAccessor
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.FromReplication && token.Local {
|
if opts.FromReplication && token.Local {
|
||||||
return fmt.Errorf("Cannot replicate local tokens")
|
return fmt.Errorf("Cannot replicate local tokens")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for an existing ACL
|
// Check for an existing ACL
|
||||||
// DEPRECATED (ACL-Legacy-Compat) - transition to using accessor index instead of secret once v1 compat is removed
|
_, existing, err := aclTokenGetFromIndex(tx, token.AccessorID, indexAccessor, nil)
|
||||||
_, existing, err := aclTokenGetFromIndex(tx, token.SecretID, "id", nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed token lookup: %s", err)
|
return fmt.Errorf("failed token lookup: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -553,7 +553,7 @@ func aclTokenSetTxn(tx WriteTxn, idx uint64, token *structs.ACLToken, opts ACLTo
|
||||||
|
|
||||||
// ACLTokenGetBySecret is used to look up an existing ACL token by its SecretID.
|
// ACLTokenGetBySecret is used to look up an existing ACL token by its SecretID.
|
||||||
func (s *Store) ACLTokenGetBySecret(ws memdb.WatchSet, secret string, entMeta *acl.EnterpriseMeta) (uint64, *structs.ACLToken, error) {
|
func (s *Store) ACLTokenGetBySecret(ws memdb.WatchSet, secret string, entMeta *acl.EnterpriseMeta) (uint64, *structs.ACLToken, error) {
|
||||||
return s.aclTokenGet(ws, secret, "id", entMeta)
|
return s.aclTokenGet(ws, secret, indexID, entMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACLTokenGetByAccessor is used to look up an existing ACL token by its AccessorID.
|
// ACLTokenGetByAccessor is used to look up an existing ACL token by its AccessorID.
|
||||||
|
|
|
@ -33,7 +33,6 @@ func setupGlobalManagement(t *testing.T, s *Store) {
|
||||||
Name: "global-management",
|
Name: "global-management",
|
||||||
Description: "Builtin Policy that grants unlimited access",
|
Description: "Builtin Policy that grants unlimited access",
|
||||||
Rules: structs.ACLPolicyGlobalManagement,
|
Rules: structs.ACLPolicyGlobalManagement,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
}
|
}
|
||||||
policy.SetHash(true)
|
policy.SetHash(true)
|
||||||
require.NoError(t, s.ACLPolicySet(1, &policy))
|
require.NoError(t, s.ACLPolicySet(1, &policy))
|
||||||
|
@ -74,35 +73,30 @@ func setupExtraPolicies(t *testing.T, s *Store) {
|
||||||
Name: "node-read",
|
Name: "node-read",
|
||||||
Description: "Allows reading all node information",
|
Description: "Allows reading all node information",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: testPolicyID_B,
|
ID: testPolicyID_B,
|
||||||
Name: "agent-read",
|
Name: "agent-read",
|
||||||
Description: "Allows reading all node information",
|
Description: "Allows reading all node information",
|
||||||
Rules: `agent_prefix "" { policy = "read" }`,
|
Rules: `agent_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: testPolicyID_C,
|
ID: testPolicyID_C,
|
||||||
Name: "acl-read",
|
Name: "acl-read",
|
||||||
Description: "Allows acl read",
|
Description: "Allows acl read",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: testPolicyID_D,
|
ID: testPolicyID_D,
|
||||||
Name: "acl-write",
|
Name: "acl-write",
|
||||||
Description: "Allows acl write",
|
Description: "Allows acl write",
|
||||||
Rules: `acl = "write"`,
|
Rules: `acl = "write"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: testPolicyID_E,
|
ID: testPolicyID_E,
|
||||||
Name: "kv-read",
|
Name: "kv-read",
|
||||||
Description: "Allows kv read",
|
Description: "Allows kv read",
|
||||||
Rules: `key_prefix "" { policy = "read" }`,
|
Rules: `key_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,7 +1062,6 @@ func TestStateStore_ACLToken_FixupPolicyLinks(t *testing.T) {
|
||||||
Name: "node-read-renamed",
|
Name: "node-read-renamed",
|
||||||
Description: "Allows reading all node information",
|
Description: "Allows reading all node information",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
}
|
}
|
||||||
renamed.SetHash(true)
|
renamed.SetHash(true)
|
||||||
require.NoError(t, s.ACLPolicySet(3, renamed))
|
require.NoError(t, s.ACLPolicySet(3, renamed))
|
||||||
|
@ -1475,7 +1468,6 @@ func TestStateStore_ACLPolicy_SetGet(t *testing.T) {
|
||||||
Name: "node-read",
|
Name: "node-read",
|
||||||
Description: "Allows reading all node information",
|
Description: "Allows reading all node information",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1488,7 +1480,6 @@ func TestStateStore_ACLPolicy_SetGet(t *testing.T) {
|
||||||
require.Equal(t, "node-read", rpolicy.Name)
|
require.Equal(t, "node-read", rpolicy.Name)
|
||||||
require.Equal(t, "Allows reading all node information", rpolicy.Description)
|
require.Equal(t, "Allows reading all node information", rpolicy.Description)
|
||||||
require.Equal(t, `node_prefix "" { policy = "read" }`, rpolicy.Rules)
|
require.Equal(t, `node_prefix "" { policy = "read" }`, rpolicy.Rules)
|
||||||
require.Equal(t, acl.SyntaxCurrent, rpolicy.Syntax)
|
|
||||||
require.Len(t, rpolicy.Datacenters, 1)
|
require.Len(t, rpolicy.Datacenters, 1)
|
||||||
require.Equal(t, "dc1", rpolicy.Datacenters[0])
|
require.Equal(t, "dc1", rpolicy.Datacenters[0])
|
||||||
require.Equal(t, uint64(3), rpolicy.CreateIndex)
|
require.Equal(t, uint64(3), rpolicy.CreateIndex)
|
||||||
|
@ -1502,7 +1493,6 @@ func TestStateStore_ACLPolicy_SetGet(t *testing.T) {
|
||||||
require.Equal(t, "global-management", rpolicy.Name)
|
require.Equal(t, "global-management", rpolicy.Name)
|
||||||
require.Equal(t, "Builtin Policy that grants unlimited access", rpolicy.Description)
|
require.Equal(t, "Builtin Policy that grants unlimited access", rpolicy.Description)
|
||||||
require.Equal(t, structs.ACLPolicyGlobalManagement, rpolicy.Rules)
|
require.Equal(t, structs.ACLPolicyGlobalManagement, rpolicy.Rules)
|
||||||
require.Equal(t, acl.SyntaxCurrent, rpolicy.Syntax)
|
|
||||||
require.Len(t, rpolicy.Datacenters, 0)
|
require.Len(t, rpolicy.Datacenters, 0)
|
||||||
require.Equal(t, uint64(1), rpolicy.CreateIndex)
|
require.Equal(t, uint64(1), rpolicy.CreateIndex)
|
||||||
require.Equal(t, uint64(1), rpolicy.ModifyIndex)
|
require.Equal(t, uint64(1), rpolicy.ModifyIndex)
|
||||||
|
@ -1518,7 +1508,6 @@ func TestStateStore_ACLPolicy_SetGet(t *testing.T) {
|
||||||
Name: "node-read-modified",
|
Name: "node-read-modified",
|
||||||
Description: "Modified",
|
Description: "Modified",
|
||||||
Rules: `node_prefix "" { policy = "read" } node "secret" { policy = "deny" }`,
|
Rules: `node_prefix "" { policy = "read" } node "secret" { policy = "deny" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1", "dc2"},
|
Datacenters: []string{"dc1", "dc2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2307,7 +2296,6 @@ func TestStateStore_ACLRole_FixupPolicyLinks(t *testing.T) {
|
||||||
Name: "node-read-renamed",
|
Name: "node-read-renamed",
|
||||||
Description: "Allows reading all node information",
|
Description: "Allows reading all node information",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
}
|
}
|
||||||
renamed.SetHash(true)
|
renamed.SetHash(true)
|
||||||
require.NoError(t, s.ACLPolicySet(3, renamed))
|
require.NoError(t, s.ACLPolicySet(3, renamed))
|
||||||
|
@ -3368,14 +3356,12 @@ func TestStateStore_ACLTokens_Snapshot_Restore(t *testing.T) {
|
||||||
Name: "policy1",
|
Name: "policy1",
|
||||||
Description: "policy1",
|
Description: "policy1",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: "7b70fa0f-58cd-412d-93c3-a0f17bb19a3e",
|
ID: "7b70fa0f-58cd-412d-93c3-a0f17bb19a3e",
|
||||||
Name: "policy2",
|
Name: "policy2",
|
||||||
Description: "policy2",
|
Description: "policy2",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3769,14 +3755,12 @@ func TestStateStore_ACLRoles_Snapshot_Restore(t *testing.T) {
|
||||||
Name: "policy1",
|
Name: "policy1",
|
||||||
Description: "policy1",
|
Description: "policy1",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
&structs.ACLPolicy{
|
&structs.ACLPolicy{
|
||||||
ID: "7b70fa0f-58cd-412d-93c3-a0f17bb19a3e",
|
ID: "7b70fa0f-58cd-412d-93c3-a0f17bb19a3e",
|
||||||
Name: "policy2",
|
Name: "policy2",
|
||||||
Description: "policy2",
|
Description: "policy2",
|
||||||
Rules: `acl = "read"`,
|
Rules: `acl = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ func TestEventPayloadCARoots_HasReadPermission(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -140,7 +140,6 @@ func TestStore_IntegrationWithEventPublisher_ACLPolicyUpdate(t *testing.T) {
|
||||||
ID: testPolicyID_C,
|
ID: testPolicyID_C,
|
||||||
Name: "foo-read",
|
Name: "foo-read",
|
||||||
Rules: `node "foo" { policy = "read" }`,
|
Rules: `node "foo" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
}
|
}
|
||||||
policy2.SetHash(false)
|
policy2.SetHash(false)
|
||||||
|
@ -154,7 +153,6 @@ func TestStore_IntegrationWithEventPublisher_ACLPolicyUpdate(t *testing.T) {
|
||||||
ID: testPolicyID_A,
|
ID: testPolicyID_A,
|
||||||
Name: "node-read",
|
Name: "node-read",
|
||||||
Rules: `node_prefix "" { policy = "write" }`,
|
Rules: `node_prefix "" { policy = "write" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
}
|
}
|
||||||
policy3.SetHash(false)
|
policy3.SetHash(false)
|
||||||
|
@ -213,7 +211,6 @@ func TestStore_IntegrationWithEventPublisher_ACLPolicyUpdate(t *testing.T) {
|
||||||
ID: testPolicyID_B,
|
ID: testPolicyID_B,
|
||||||
Name: "node-read",
|
Name: "node-read",
|
||||||
Rules: `node_prefix "foo" { policy = "read" }`,
|
Rules: `node_prefix "foo" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: []string{"dc1"},
|
Datacenters: []string{"dc1"},
|
||||||
}
|
}
|
||||||
policy4.SetHash(false)
|
policy4.SetHash(false)
|
||||||
|
|
|
@ -47,7 +47,7 @@ func ACLServiceWriteAny(t *testing.T) resolver.Result {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -692,7 +692,7 @@ node "node1" {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
cfg := &acl.Config{WildcardName: structs.WildcardSpecifier}
|
cfg := &acl.Config{WildcardName: structs.WildcardSpecifier}
|
||||||
authorizer, err := acl.NewAuthorizerFromRules(rules, acl.SyntaxCurrent, cfg, nil)
|
authorizer, err := acl.NewAuthorizerFromRules(rules, cfg, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authorizer = acl.NewChainedAuthorizer([]acl.Authorizer{authorizer, acl.DenyAll()})
|
authorizer = acl.NewChainedAuthorizer([]acl.Authorizer{authorizer, acl.DenyAll()})
|
||||||
require.Equal(t, acl.Deny, authorizer.NodeRead("denied", nil))
|
require.Equal(t, acl.Deny, authorizer.NodeRead("denied", nil))
|
||||||
|
@ -896,7 +896,7 @@ node "node1" {
|
||||||
policy = "write"
|
policy = "write"
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
authorizer, err := acl.NewAuthorizerFromRules(rules, acl.SyntaxCurrent, &acl.Config{WildcardName: structs.WildcardSpecifier}, nil)
|
authorizer, err := acl.NewAuthorizerFromRules(rules, &acl.Config{WildcardName: structs.WildcardSpecifier}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authorizer = acl.NewChainedAuthorizer([]acl.Authorizer{authorizer, acl.DenyAll()})
|
authorizer = acl.NewChainedAuthorizer([]acl.Authorizer{authorizer, acl.DenyAll()})
|
||||||
require.Equal(t, acl.Deny, authorizer.NodeRead("denied", nil))
|
require.Equal(t, acl.Deny, authorizer.NodeRead("denied", nil))
|
||||||
|
|
|
@ -91,7 +91,7 @@ func disableLegacyIntentions(t *testing.T, store *state.Store) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func policyAuthorizer(t *testing.T, policyHCL string) acl.Authorizer {
|
func policyAuthorizer(t *testing.T, policyHCL string) acl.Authorizer {
|
||||||
policy, err := acl.NewPolicyFromSource(policyHCL, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(policyHCL, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -1732,25 +1732,21 @@ func upsertTestACLs(t *testing.T, store *state.Store) {
|
||||||
ID: testPolicyPeeringReadID,
|
ID: testPolicyPeeringReadID,
|
||||||
Name: "peering-read",
|
Name: "peering-read",
|
||||||
Rules: `peering = "read"`,
|
Rules: `peering = "read"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: testPolicyPeeringWriteID,
|
ID: testPolicyPeeringWriteID,
|
||||||
Name: "peering-write",
|
Name: "peering-write",
|
||||||
Rules: `peering = "write"`,
|
Rules: `peering = "write"`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: testPolicyServiceReadID,
|
ID: testPolicyServiceReadID,
|
||||||
Name: "service-read",
|
Name: "service-read",
|
||||||
Rules: `service "api" { policy = "read" }`,
|
Rules: `service "api" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: testPolicyServiceWriteID,
|
ID: testPolicyServiceWriteID,
|
||||||
Name: "service-write",
|
Name: "service-write",
|
||||||
Rules: `service "api" { policy = "write" }`,
|
Rules: `service "api" { policy = "write" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
require.NoError(t, store.ACLPolicyBatchSet(100, policies))
|
require.NoError(t, store.ACLPolicyBatchSet(100, policies))
|
||||||
|
|
|
@ -160,7 +160,6 @@ func (s *ACLServiceIdentity) SyntheticPolicy(entMeta *acl.EnterpriseMeta) *ACLPo
|
||||||
sn := NewServiceName(s.ServiceName, entMeta)
|
sn := NewServiceName(s.ServiceName, entMeta)
|
||||||
policy.Description = fmt.Sprintf("synthetic policy for service identity %q", sn.String())
|
policy.Description = fmt.Sprintf("synthetic policy for service identity %q", sn.String())
|
||||||
policy.Rules = rules
|
policy.Rules = rules
|
||||||
policy.Syntax = acl.SyntaxCurrent
|
|
||||||
policy.Datacenters = s.Datacenters
|
policy.Datacenters = s.Datacenters
|
||||||
policy.EnterpriseMeta.Merge(entMeta)
|
policy.EnterpriseMeta.Merge(entMeta)
|
||||||
policy.SetHash(true)
|
policy.SetHash(true)
|
||||||
|
@ -232,7 +231,6 @@ func (s *ACLNodeIdentity) SyntheticPolicy(entMeta *acl.EnterpriseMeta) *ACLPolic
|
||||||
policy.Name = fmt.Sprintf("synthetic-policy-%s", hashID)
|
policy.Name = fmt.Sprintf("synthetic-policy-%s", hashID)
|
||||||
policy.Description = fmt.Sprintf("synthetic policy for node identity %q", s.NodeName)
|
policy.Description = fmt.Sprintf("synthetic policy for node identity %q", s.NodeName)
|
||||||
policy.Rules = rules
|
policy.Rules = rules
|
||||||
policy.Syntax = acl.SyntaxCurrent
|
|
||||||
policy.Datacenters = []string{s.Datacenter}
|
policy.Datacenters = []string{s.Datacenter}
|
||||||
policy.EnterpriseMeta.Merge(entMeta)
|
policy.EnterpriseMeta.Merge(entMeta)
|
||||||
policy.SetHash(true)
|
policy.SetHash(true)
|
||||||
|
@ -286,13 +284,6 @@ type ACLToken struct {
|
||||||
// The node identities that this token should be allowed to manage.
|
// The node identities that this token should be allowed to manage.
|
||||||
NodeIdentities ACLNodeIdentities `json:",omitempty"`
|
NodeIdentities ACLNodeIdentities `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
|
|
||||||
// want to be able to have the old APIs operate on the upgraded management tokens
|
|
||||||
// so this field is being kept to identify legacy tokens even after an auto-upgrade
|
|
||||||
Type string `json:"-"`
|
|
||||||
|
|
||||||
// Whether this token is DC local. This means that it will not be synced
|
// Whether this token is DC local. This means that it will not be synced
|
||||||
// to the ACL datacenter and replicated to others.
|
// to the ACL datacenter and replicated to others.
|
||||||
Local bool
|
Local bool
|
||||||
|
@ -479,7 +470,6 @@ func (t *ACLToken) SetHash(force bool) []byte {
|
||||||
|
|
||||||
// Write all the user set fields
|
// Write all the user set fields
|
||||||
hash.Write([]byte(t.Description))
|
hash.Write([]byte(t.Description))
|
||||||
hash.Write([]byte(t.Type))
|
|
||||||
|
|
||||||
if t.Local {
|
if t.Local {
|
||||||
hash.Write([]byte("local"))
|
hash.Write([]byte("local"))
|
||||||
|
@ -516,7 +506,7 @@ func (t *ACLToken) SetHash(force bool) []byte {
|
||||||
|
|
||||||
func (t *ACLToken) EstimateSize() int {
|
func (t *ACLToken) EstimateSize() int {
|
||||||
// 41 = 16 (RaftIndex) + 8 (Hash) + 8 (ExpirationTime) + 8 (CreateTime) + 1 (Local)
|
// 41 = 16 (RaftIndex) + 8 (Hash) + 8 (ExpirationTime) + 8 (CreateTime) + 1 (Local)
|
||||||
size := 41 + len(t.AccessorID) + len(t.SecretID) + len(t.Description) + len(t.Type) + len(t.AuthMethod)
|
size := 41 + len(t.AccessorID) + len(t.SecretID) + len(t.Description) + len(t.AuthMethod)
|
||||||
for _, link := range t.Policies {
|
for _, link := range t.Policies {
|
||||||
size += len(link.ID) + len(link.Name)
|
size += len(link.ID) + len(link.Name)
|
||||||
}
|
}
|
||||||
|
@ -604,9 +594,6 @@ type ACLPolicy struct {
|
||||||
// The rule set (using the updated rule syntax)
|
// The rule set (using the updated rule syntax)
|
||||||
Rules string
|
Rules string
|
||||||
|
|
||||||
// DEPRECATED (ACL-Legacy-Compat) - This is only needed while we support the legacy ACLs
|
|
||||||
Syntax acl.SyntaxVersion `json:"-"`
|
|
||||||
|
|
||||||
// Datacenters that the policy is valid within.
|
// Datacenters that the policy is valid within.
|
||||||
// - No wildcards allowed
|
// - No wildcards allowed
|
||||||
// - If empty then the policy is valid within all datacenters
|
// - If empty then the policy is valid within all datacenters
|
||||||
|
@ -767,7 +754,7 @@ func (policies ACLPolicies) resolveWithCache(cache *ACLCaches, entConf *acl.Conf
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := acl.NewPolicyFromSource(policy.Rules, policy.Syntax, entConf, policy.EnterprisePolicyMeta())
|
p, err := acl.NewPolicyFromSource(policy.Rules, entConf, policy.EnterprisePolicyMeta())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse %q: %v", policy.Name, err)
|
return nil, fmt.Errorf("failed to parse %q: %v", policy.Name, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,6 @@ func TestStructs_ACLServiceIdentity_SyntheticPolicy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expect := &ACLPolicy{
|
expect := &ACLPolicy{
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
Datacenters: test.datacenters,
|
Datacenters: test.datacenters,
|
||||||
Rules: test.expectRules,
|
Rules: test.expectRules,
|
||||||
}
|
}
|
||||||
|
@ -402,7 +401,6 @@ func TestStructs_ACLPolicies_resolveWithCache(t *testing.T) {
|
||||||
Name: "policy1",
|
Name: "policy1",
|
||||||
Description: "policy1",
|
Description: "policy1",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 1,
|
CreateIndex: 1,
|
||||||
ModifyIndex: 2,
|
ModifyIndex: 2,
|
||||||
|
@ -413,7 +411,6 @@ func TestStructs_ACLPolicies_resolveWithCache(t *testing.T) {
|
||||||
Name: "policy2",
|
Name: "policy2",
|
||||||
Description: "policy2",
|
Description: "policy2",
|
||||||
Rules: `agent_prefix "" { policy = "read" }`,
|
Rules: `agent_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 3,
|
CreateIndex: 3,
|
||||||
ModifyIndex: 4,
|
ModifyIndex: 4,
|
||||||
|
@ -424,7 +421,6 @@ func TestStructs_ACLPolicies_resolveWithCache(t *testing.T) {
|
||||||
Name: "policy3",
|
Name: "policy3",
|
||||||
Description: "policy3",
|
Description: "policy3",
|
||||||
Rules: `key_prefix "" { policy = "read" }`,
|
Rules: `key_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 5,
|
CreateIndex: 5,
|
||||||
ModifyIndex: 6,
|
ModifyIndex: 6,
|
||||||
|
@ -435,7 +431,6 @@ func TestStructs_ACLPolicies_resolveWithCache(t *testing.T) {
|
||||||
Name: "policy4",
|
Name: "policy4",
|
||||||
Description: "policy4",
|
Description: "policy4",
|
||||||
Rules: `service_prefix "" { policy = "read" }`,
|
Rules: `service_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 7,
|
CreateIndex: 7,
|
||||||
ModifyIndex: 8,
|
ModifyIndex: 8,
|
||||||
|
@ -492,7 +487,6 @@ func TestStructs_ACLPolicies_Compile(t *testing.T) {
|
||||||
Name: "policy1",
|
Name: "policy1",
|
||||||
Description: "policy1",
|
Description: "policy1",
|
||||||
Rules: `node_prefix "" { policy = "read" }`,
|
Rules: `node_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 1,
|
CreateIndex: 1,
|
||||||
ModifyIndex: 2,
|
ModifyIndex: 2,
|
||||||
|
@ -503,7 +497,6 @@ func TestStructs_ACLPolicies_Compile(t *testing.T) {
|
||||||
Name: "policy2",
|
Name: "policy2",
|
||||||
Description: "policy2",
|
Description: "policy2",
|
||||||
Rules: `agent_prefix "" { policy = "read" }`,
|
Rules: `agent_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 3,
|
CreateIndex: 3,
|
||||||
ModifyIndex: 4,
|
ModifyIndex: 4,
|
||||||
|
@ -514,7 +507,6 @@ func TestStructs_ACLPolicies_Compile(t *testing.T) {
|
||||||
Name: "policy3",
|
Name: "policy3",
|
||||||
Description: "policy3",
|
Description: "policy3",
|
||||||
Rules: `key_prefix "" { policy = "read" }`,
|
Rules: `key_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 5,
|
CreateIndex: 5,
|
||||||
ModifyIndex: 6,
|
ModifyIndex: 6,
|
||||||
|
@ -525,7 +517,6 @@ func TestStructs_ACLPolicies_Compile(t *testing.T) {
|
||||||
Name: "policy4",
|
Name: "policy4",
|
||||||
Description: "policy4",
|
Description: "policy4",
|
||||||
Rules: `service_prefix "" { policy = "read" }`,
|
Rules: `service_prefix "" { policy = "read" }`,
|
||||||
Syntax: acl.SyntaxCurrent,
|
|
||||||
RaftIndex: RaftIndex{
|
RaftIndex: RaftIndex{
|
||||||
CreateIndex: 7,
|
CreateIndex: 7,
|
||||||
ModifyIndex: 8,
|
ModifyIndex: 8,
|
||||||
|
|
|
@ -28,7 +28,7 @@ func TestACL_filterImported_IndexedHealthChecks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -99,7 +99,7 @@ func TestACL_filterImported_IndexedNodes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -172,7 +172,7 @@ func TestACL_filterImported_IndexedNodeServices(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -253,7 +253,7 @@ func TestACL_filterImported_IndexedNodeServiceList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -333,7 +333,7 @@ func TestACL_filterImported_IndexedServiceNodes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -402,7 +402,7 @@ func TestACL_filterImported_CheckServiceNode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
run := func(t *testing.T, tc testCase) {
|
run := func(t *testing.T, tc testCase) {
|
||||||
policy, err := acl.NewPolicyFromSource(tc.policyRules, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tc.policyRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -505,10 +505,16 @@ func TestACL_filterHealthChecks(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
|
service_prefix "foo" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
node_prefix "node1" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -527,7 +533,10 @@ func TestACL_filterHealthChecks(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
service_prefix "foo" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -546,7 +555,10 @@ func TestACL_filterHealthChecks(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
node_prefix "node1" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -604,7 +616,10 @@ func TestACL_filterIntentions(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
service_prefix "foo" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -675,7 +690,7 @@ func TestACL_filterServiceNodes(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -694,7 +709,7 @@ func TestACL_filterServiceNodes(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -758,7 +773,7 @@ func TestACL_filterNodeServices(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -777,7 +792,7 @@ func TestACL_filterNodeServices(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -796,7 +811,7 @@ func TestACL_filterNodeServices(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -855,7 +870,7 @@ func TestACL_filterNodeServiceList(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -874,7 +889,7 @@ func TestACL_filterNodeServiceList(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -893,7 +908,7 @@ func TestACL_filterNodeServiceList(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -936,7 +951,7 @@ func TestACL_filterGatewayServices(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -996,7 +1011,7 @@ func TestACL_filterCheckServiceNodes(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1015,7 +1030,7 @@ func TestACL_filterCheckServiceNodes(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1034,7 +1049,7 @@ func TestACL_filterCheckServiceNodes(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1094,7 +1109,7 @@ func TestACL_filterPreparedQueryExecuteResponse(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1113,7 +1128,7 @@ func TestACL_filterPreparedQueryExecuteResponse(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1132,7 +1147,7 @@ func TestACL_filterPreparedQueryExecuteResponse(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1231,7 +1246,7 @@ node "node1" {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}`
|
}`
|
||||||
policy, err := acl.NewPolicyFromSource(rules, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(rules, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err %v", err)
|
t.Fatalf("err %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1259,7 +1274,7 @@ node "node2" {
|
||||||
service "bar" {
|
service "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}`
|
}`
|
||||||
policy, err := acl.NewPolicyFromSource(rules, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(rules, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err %v", err)
|
t.Fatalf("err %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1293,7 +1308,7 @@ node "node2" {
|
||||||
service "bar" {
|
service "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}`
|
}`
|
||||||
policy, err := acl.NewPolicyFromSource(rules, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(rules, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err %v", err)
|
t.Fatalf("err %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1344,7 +1359,7 @@ func TestACL_filterCoordinates(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1396,7 +1411,7 @@ func TestACL_filterSessions(t *testing.T) {
|
||||||
session "foo" {
|
session "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1500,7 +1515,7 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1520,7 +1535,7 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1549,7 +1564,7 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1587,7 +1602,7 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
service "" {
|
service "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1607,8 +1622,11 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
policy, err := acl.NewPolicyFromSource(`
|
policy, err := acl.NewPolicyFromSource(`
|
||||||
node "" {
|
node "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
|
},
|
||||||
|
node_prefix "" {
|
||||||
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1640,11 +1658,17 @@ func TestACL_filterNodeDump(t *testing.T) {
|
||||||
policy, err := acl.NewPolicyFromSource(`
|
policy, err := acl.NewPolicyFromSource(`
|
||||||
service "" {
|
service "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
|
},
|
||||||
|
service_prefix "" {
|
||||||
|
policy = "read"
|
||||||
}
|
}
|
||||||
node "" {
|
node "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
|
},
|
||||||
|
node_prefix "" {
|
||||||
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1813,7 +1837,7 @@ func TestACL_filterIndexedNodesWithGateways(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1877,7 +1901,7 @@ func TestACL_filterIndexedNodesWithGateways(t *testing.T) {
|
||||||
service "bar" {
|
service "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1903,7 +1927,7 @@ func TestACL_filterIndexedNodesWithGateways(t *testing.T) {
|
||||||
service "bar" {
|
service "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -1928,7 +1952,7 @@ func TestACL_filterIndexedNodesWithGateways(t *testing.T) {
|
||||||
node "node1" {
|
node "node1" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2022,7 +2046,7 @@ func TestACL_filterIndexedServiceDump(t *testing.T) {
|
||||||
service_prefix "bar" {
|
service_prefix "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2044,7 +2068,7 @@ func TestACL_filterIndexedServiceDump(t *testing.T) {
|
||||||
service_prefix "bar" {
|
service_prefix "bar" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2067,7 +2091,7 @@ func TestACL_filterIndexedServiceDump(t *testing.T) {
|
||||||
service "foo-gateway" {
|
service "foo-gateway" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2089,7 +2113,7 @@ func TestACL_filterIndexedServiceDump(t *testing.T) {
|
||||||
service "foo" {
|
service "foo" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2164,7 +2188,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
|
||||||
service_prefix "" {
|
service_prefix "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2184,7 +2208,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
|
||||||
service_prefix "" {
|
service_prefix "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2203,7 +2227,7 @@ func TestACL_filterDatacenterCheckServiceNodes(t *testing.T) {
|
||||||
node_prefix "" {
|
node_prefix "" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxCurrent, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2360,7 +2384,7 @@ func TestACL_filterPreparedQueries(t *testing.T) {
|
||||||
query "query-with-a-token" {
|
query "query-with-a-token" {
|
||||||
policy = "read"
|
policy = "read"
|
||||||
}
|
}
|
||||||
`, acl.SyntaxLegacy, nil, nil)
|
`, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -2432,7 +2456,7 @@ func TestACL_unhandledFilterType(t *testing.T) {
|
||||||
func policy(t *testing.T, hcl string) acl.Authorizer {
|
func policy(t *testing.T, hcl string) acl.Authorizer {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
policy, err := acl.NewPolicyFromSource(hcl, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(hcl, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestConfigEntries_ListRelatedServices_AndACLs(t *testing.T) {
|
||||||
// This test tests both of these because they are related functions.
|
// This test tests both of these because they are related functions.
|
||||||
|
|
||||||
newAuthz := func(t *testing.T, src string) acl.Authorizer {
|
newAuthz := func(t *testing.T, src string) acl.Authorizer {
|
||||||
policy, err := acl.NewPolicyFromSource(src, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(src, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
@ -34,7 +34,7 @@ func TestConfigEntries_ListRelatedServices_AndACLs(t *testing.T) {
|
||||||
buf.WriteString(fmt.Sprintf("service %q { policy = %q }\n", s, "write"))
|
buf.WriteString(fmt.Sprintf("service %q { policy = %q }\n", s, "write"))
|
||||||
}
|
}
|
||||||
|
|
||||||
policy, err := acl.NewPolicyFromSource(buf.String(), acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(buf.String(), nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -26,7 +26,7 @@ func TestConfigEntries_ACLs(t *testing.T) {
|
||||||
type testcase = configEntryACLTestCase
|
type testcase = configEntryACLTestCase
|
||||||
|
|
||||||
newAuthz := func(t *testing.T, src string) acl.Authorizer {
|
newAuthz := func(t *testing.T, src string) acl.Authorizer {
|
||||||
policy, err := acl.NewPolicyFromSource(src, acl.SyntaxCurrent, nil, nil)
|
policy, err := acl.NewPolicyFromSource(src, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
authorizer, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||||
|
|
|
@ -117,7 +117,7 @@ func TestIntention_ACLs(t *testing.T) {
|
||||||
|
|
||||||
for name, tcase := range cases {
|
for name, tcase := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
authz, err := acl.NewAuthorizerFromRules(tcase.rules, acl.SyntaxCurrent, &config, nil)
|
authz, err := acl.NewAuthorizerFromRules(tcase.rules, &config, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, tcase.read, tcase.intention.CanRead(authz))
|
require.Equal(t, tcase.read, tcase.intention.CanRead(authz))
|
||||||
|
|
|
@ -1069,7 +1069,7 @@ func TestServer_DeltaAggregatedResources_v3_ACLEnforcement(t *testing.T) {
|
||||||
// Ensure the correct token was passed
|
// Ensure the correct token was passed
|
||||||
require.Equal(t, tt.token, id)
|
require.Equal(t, tt.token, id)
|
||||||
// Parse the ACL and enforce it
|
// Parse the ACL and enforce it
|
||||||
policy, err := acl.NewPolicyFromSource(tt.acl, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(tt.acl, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return acl.NewPolicyAuthorizerWithDefaults(acl.RootAuthorizer("deny"), []*acl.Policy{policy}, nil)
|
return acl.NewPolicyAuthorizerWithDefaults(acl.RootAuthorizer("deny"), []*acl.Policy{policy}, nil)
|
||||||
}
|
}
|
||||||
|
@ -1158,7 +1158,7 @@ func TestServer_DeltaAggregatedResources_v3_ACLTokenDeleted_StreamTerminatedDuri
|
||||||
aclRules := `service "web" { policy = "write" }`
|
aclRules := `service "web" { policy = "write" }`
|
||||||
token := "service-write-on-web"
|
token := "service-write-on-web"
|
||||||
|
|
||||||
policy, err := acl.NewPolicyFromSource(aclRules, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(aclRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var validToken atomic.Value
|
var validToken atomic.Value
|
||||||
|
@ -1256,7 +1256,7 @@ func TestServer_DeltaAggregatedResources_v3_ACLTokenDeleted_StreamTerminatedInBa
|
||||||
aclRules := `service "web" { policy = "write" }`
|
aclRules := `service "web" { policy = "write" }`
|
||||||
token := "service-write-on-web"
|
token := "service-write-on-web"
|
||||||
|
|
||||||
policy, err := acl.NewPolicyFromSource(aclRules, acl.SyntaxLegacy, nil, nil)
|
policy, err := acl.NewPolicyFromSource(aclRules, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var validToken atomic.Value
|
var validToken atomic.Value
|
||||||
|
|
|
@ -201,11 +201,11 @@ const (
|
||||||
// ACLModeEnabled indicates that ACLs are enabled and operating in new ACL
|
// ACLModeEnabled indicates that ACLs are enabled and operating in new ACL
|
||||||
// mode (v1.4.0+ ACLs)
|
// mode (v1.4.0+ ACLs)
|
||||||
ACLModeEnabled MemberACLMode = "1"
|
ACLModeEnabled MemberACLMode = "1"
|
||||||
// ACLModeLegacy indicates that ACLs are enabled and operating in legacy mode.
|
// ACLModeLegacy has been deprecated, and will be treated as ACLModeUnknown.
|
||||||
ACLModeLegacy MemberACLMode = "2"
|
ACLModeLegacy MemberACLMode = "2" // DEPRECATED
|
||||||
// ACLModeUnkown is used to indicate that the AgentMember.Tags didn't advertise
|
// ACLModeUnkown is used to indicate that the AgentMember.Tags didn't advertise
|
||||||
// an ACL mode at all. This is the case for Consul versions before v1.4.0 and
|
// an ACL mode at all. This is the case for Consul versions before v1.4.0 and
|
||||||
// should be treated similarly to ACLModeLegacy.
|
// should be treated the same as ACLModeLegacy.
|
||||||
ACLModeUnknown MemberACLMode = "3"
|
ACLModeUnknown MemberACLMode = "3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -244,8 +244,6 @@ func (m *AgentMember) ACLMode() MemberACLMode {
|
||||||
return ACLModeDisabled
|
return ACLModeDisabled
|
||||||
case ACLModeEnabled:
|
case ACLModeEnabled:
|
||||||
return ACLModeEnabled
|
return ACLModeEnabled
|
||||||
case ACLModeLegacy:
|
|
||||||
return ACLModeLegacy
|
|
||||||
default:
|
default:
|
||||||
return ACLModeUnknown
|
return ACLModeUnknown
|
||||||
}
|
}
|
||||||
|
|
|
@ -2017,7 +2017,7 @@ func TestMemberACLMode(t *testing.T) {
|
||||||
},
|
},
|
||||||
"legacy": {
|
"legacy": {
|
||||||
tagValue: "2",
|
tagValue: "2",
|
||||||
expectedMode: ACLModeLegacy,
|
expectedMode: ACLModeUnknown,
|
||||||
},
|
},
|
||||||
"unknown-3": {
|
"unknown-3": {
|
||||||
tagValue: "3",
|
tagValue: "3",
|
||||||
|
|
|
@ -908,15 +908,6 @@ func TestAPI_Headers(t *testing.T) {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
|
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
|
||||||
|
|
||||||
_, err = c.ACL().RulesTranslate(strings.NewReader(`
|
|
||||||
agent "" {
|
|
||||||
policy = "read"
|
|
||||||
}
|
|
||||||
`))
|
|
||||||
// ACL support is disabled
|
|
||||||
require.Error(t, err)
|
|
||||||
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
|
|
||||||
|
|
||||||
_, _, err = c.Event().Fire(&UserEvent{
|
_, _, err = c.Event().Fire(&UserEvent{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Payload: []byte("foo"),
|
Payload: []byte("foo"),
|
||||||
|
@ -925,6 +916,24 @@ func TestAPI_Headers(t *testing.T) {
|
||||||
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
|
require.Equal(t, "application/octet-stream", request.Header.Get("Content-Type"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPI_Deprecated(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c, s := makeClientWithConfig(t, func(c *Config) {
|
||||||
|
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
|
c.Transport = transport
|
||||||
|
}, nil)
|
||||||
|
defer s.Stop()
|
||||||
|
// Rules translation functionality was completely removed in Consul 1.15.
|
||||||
|
_, err := c.ACL().RulesTranslate(strings.NewReader(`
|
||||||
|
agent "" {
|
||||||
|
policy = "read"
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
require.Error(t, err)
|
||||||
|
_, err = c.ACL().RulesTranslateToken("")
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPI_RequestToHTTP(t *testing.T) {
|
func TestAPI_RequestToHTTP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c, s := makeClient(t)
|
c, s := makeClient(t)
|
||||||
|
|
|
@ -30,9 +30,6 @@ type License struct {
|
||||||
// no longer be used in any capacity
|
// no longer be used in any capacity
|
||||||
TerminationTime time.Time `json:"termination_time"`
|
TerminationTime time.Time `json:"termination_time"`
|
||||||
|
|
||||||
// Whether the license will ignore termination
|
|
||||||
IgnoreTermination bool `json:"ignore_termination"`
|
|
||||||
|
|
||||||
// The product the license is valid for
|
// The product the license is valid for
|
||||||
Product string `json:"product"`
|
Product string `json:"product"`
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import BaseAbility from './base';
|
import BaseAbility from './base';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
|
||||||
import { isLegacy } from 'consul-ui/helpers/token/is-legacy';
|
|
||||||
import { isAnonymous } from 'consul-ui/helpers/token/is-anonymous';
|
import { isAnonymous } from 'consul-ui/helpers/token/is-anonymous';
|
||||||
|
|
||||||
export default class TokenAbility extends BaseAbility {
|
export default class TokenAbility extends BaseAbility {
|
||||||
|
@ -28,6 +27,6 @@ export default class TokenAbility extends BaseAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
get canDuplicate() {
|
get canDuplicate() {
|
||||||
return this.env.var('CONSUL_ACLS_ENABLED') && !isLegacy([this.item]) && super.canWrite;
|
return this.env.var('CONSUL_ACLS_ENABLED') && super.canWrite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ export default class Token extends Model {
|
||||||
@attr('string') IDPName;
|
@attr('string') IDPName;
|
||||||
@attr('string') SecretID;
|
@attr('string') SecretID;
|
||||||
|
|
||||||
@attr('boolean') Legacy;
|
|
||||||
@attr('boolean') Local;
|
@attr('boolean') Local;
|
||||||
@attr('string', { defaultValue: () => '' }) Description;
|
@attr('string', { defaultValue: () => '' }) Description;
|
||||||
@attr() meta; // {}
|
@attr() meta; // {}
|
||||||
|
@ -29,12 +28,6 @@ export default class Token extends Model {
|
||||||
@attr('number') CreateIndex;
|
@attr('number') CreateIndex;
|
||||||
@attr('number') ModifyIndex;
|
@attr('number') ModifyIndex;
|
||||||
|
|
||||||
// Legacy
|
|
||||||
@attr('string') Type;
|
|
||||||
@attr('string', { defaultValue: () => '' }) Name;
|
|
||||||
@attr('string') Rules;
|
|
||||||
// End Legacy
|
|
||||||
|
|
||||||
@computed('Policies.[]')
|
@computed('Policies.[]')
|
||||||
get isGlobalManagement() {
|
get isGlobalManagement() {
|
||||||
return (this.Policies || []).find((item) => item.ID === MANAGEMENT_ID);
|
return (this.Policies || []).find((item) => item.ID === MANAGEMENT_ID);
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { module, test } from 'qunit';
|
|
||||||
import { setupRenderingTest } from 'ember-qunit';
|
|
||||||
import { render } from '@ember/test-helpers';
|
|
||||||
import hbs from 'htmlbars-inline-precompile';
|
|
||||||
|
|
||||||
module('Integration | Helper | token/is-legacy', function (hooks) {
|
|
||||||
setupRenderingTest(hooks);
|
|
||||||
|
|
||||||
// Replace this with your real tests.
|
|
||||||
test('it renders', async function (assert) {
|
|
||||||
this.set('inputValue', {});
|
|
||||||
|
|
||||||
await render(hbs`{{token/is-legacy inputValue}}`);
|
|
||||||
|
|
||||||
assert.equal(this.element.textContent.trim(), 'false');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,53 +0,0 @@
|
||||||
import { isLegacy } from 'consul-ui/helpers/token/is-legacy';
|
|
||||||
import { module, test } from 'qunit';
|
|
||||||
|
|
||||||
module('Unit | Helper | token/is-legacy', function () {
|
|
||||||
test('it returns true if the token has a Legacy=true', function (assert) {
|
|
||||||
const actual = isLegacy([{ Legacy: true }]);
|
|
||||||
assert.ok(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if the token has a Legacy=false', function (assert) {
|
|
||||||
const actual = isLegacy([{ Legacy: false }]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
test('it returns true if the token has Rules', function (assert) {
|
|
||||||
const actual = isLegacy([{ Rules: 'some rules' }]);
|
|
||||||
assert.ok(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if the token has Rules but those rules are empty', function (assert) {
|
|
||||||
const actual = isLegacy([{ Rules: '' }]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if the token has Rules but those rules is null', function (assert) {
|
|
||||||
const actual = isLegacy([{ Rules: null }]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
// passing arrays
|
|
||||||
test("it returns false if things don't have Legacy or Rules", function (assert) {
|
|
||||||
const actual = isLegacy([[{}, {}]]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
test('it returns true if the token has a Legacy=true', function (assert) {
|
|
||||||
const actual = isLegacy([[{}, { Legacy: true }]]);
|
|
||||||
assert.ok(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if the token has a Legacy=false', function (assert) {
|
|
||||||
const actual = isLegacy([[{}, { Legacy: false }]]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
test('it returns true if one token has Rules', function (assert) {
|
|
||||||
const actual = isLegacy([[{}, { Rules: 'some rules' }]]);
|
|
||||||
assert.ok(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if tokens have no Rules, or has Rules but those rules are empty', function (assert) {
|
|
||||||
const actual = isLegacy([[{}, { Rules: '' }]]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
test('it returns false if a token is marked as legacy, has Rules but those rules are empty', function (assert) {
|
|
||||||
// this may seem strange, but empty Rules should override Legacy, this only happens
|
|
||||||
// when a legacy token that has already been loaded has its rules wiped out
|
|
||||||
// WITHOUT then the ui refreshing
|
|
||||||
const actual = isLegacy([{ Legacy: true, Rules: '' }]);
|
|
||||||
assert.notOk(actual);
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue