github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/e2e/acl/acl_role_test.go (about) 1 package acl 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/nomad/api" 8 "github.com/hashicorp/nomad/e2e/e2eutil" 9 "github.com/hashicorp/nomad/helper/uuid" 10 "github.com/stretchr/testify/require" 11 ) 12 13 // testACLRole tests basic functionality of ACL roles when used for 14 // authorization. It also performs some basic token and policy tests due to the 15 // coupling between the ACL objects. 16 func testACLRole(t *testing.T) { 17 18 nomadClient := e2eutil.NomadClient(t) 19 20 // Create and defer the cleanup process. This is used to remove all 21 // resources created by this test and covers situations where the test 22 // fails or during normal running. 23 cleanUpProcess := newCleanup() 24 defer cleanUpProcess.run(t, nomadClient) 25 26 // An ACL role must reference an ACL policy that is stored in state. Ensure 27 // this behaviour by attempting to create a role that links to a policy 28 // that does not exist. 29 invalidRole := api.ACLRole{ 30 Name: "e2e-acl-" + uuid.Short(), 31 Description: "E2E ACL Role Testing", 32 Policies: []*api.ACLRolePolicyLink{{Name: "404-not-found"}}, 33 } 34 aclRoleCreateResp, _, err := nomadClient.ACLRoles().Create(&invalidRole, nil) 35 require.ErrorContains(t, err, "cannot find policy 404-not-found") 36 require.Nil(t, aclRoleCreateResp) 37 38 // Create a custom namespace to test along with the default. 39 ns := api.Namespace{ 40 Name: "e2e-acl-" + uuid.Short(), 41 Description: "E2E ACL Role Testing", 42 } 43 _, err = nomadClient.Namespaces().Register(&ns, nil) 44 require.NoError(t, err) 45 46 cleanUpProcess.add(ns.Name, namespaceTestResourceType) 47 48 // Create an ACL policy which will be used to link from the role. This 49 // policy grants read access to our custom namespace. 50 customNamespacePolicy := api.ACLPolicy{ 51 Name: "e2e-acl-" + uuid.Short(), 52 Description: "E2E ACL Role Testing", 53 Rules: fmt.Sprintf(`namespace %q {policy = "read"}`, ns.Name), 54 } 55 _, err = nomadClient.ACLPolicies().Upsert(&customNamespacePolicy, nil) 56 require.NoError(t, err) 57 58 cleanUpProcess.add(customNamespacePolicy.Name, aclPolicyTestResourceType) 59 60 // Create a valid role with a link to the previously created policy. 61 validRole := api.ACLRole{ 62 Name: "e2e-acl-" + uuid.Short(), 63 Description: "E2E ACL Role Testing", 64 Policies: []*api.ACLRolePolicyLink{{Name: customNamespacePolicy.Name}}, 65 } 66 aclRoleCreateResp, _, err = nomadClient.ACLRoles().Create(&validRole, nil) 67 require.NoError(t, err) 68 require.NotNil(t, aclRoleCreateResp) 69 require.NotEmpty(t, aclRoleCreateResp.ID) 70 require.Equal(t, validRole.Name, aclRoleCreateResp.Name) 71 72 cleanUpProcess.add(aclRoleCreateResp.ID, aclRoleTestResourceType) 73 74 // Perform a role listing and check we have the expected entries. 75 aclRoleListResp, _, err := nomadClient.ACLRoles().List(nil) 76 require.NoError(t, err) 77 require.Len(t, aclRoleListResp, 1) 78 require.Equal(t, aclRoleCreateResp.ID, aclRoleListResp[0].ID) 79 80 // Create our ACL token which is linked to the created ACL role. 81 token := api.ACLToken{ 82 Name: "e2e-acl-" + uuid.Short(), 83 Type: "client", 84 Roles: []*api.ACLTokenRoleLink{{ID: aclRoleCreateResp.ID}}, 85 } 86 aclTokenCreateResp, _, err := nomadClient.ACLTokens().Create(&token, nil) 87 require.NoError(t, err) 88 require.NotNil(t, aclTokenCreateResp) 89 90 cleanUpProcess.add(aclTokenCreateResp.AccessorID, aclTokenTestResourceType) 91 92 // Attempt two job listings against the two available namespaces. The token 93 // only has access to the custom namespace, so the default should return an 94 // error. 95 customNSQueryMeta := api.QueryOptions{Namespace: ns.Name, AuthToken: aclTokenCreateResp.SecretID} 96 defaultNSQueryMeta := api.QueryOptions{Namespace: "default", AuthToken: aclTokenCreateResp.SecretID} 97 98 jobListResp, _, err := nomadClient.Jobs().List(&customNSQueryMeta) 99 require.NoError(t, err) 100 require.Empty(t, jobListResp) 101 102 jobListResp, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta) 103 require.ErrorContains(t, err, "Permission denied") 104 105 // Create an ACL policy which grants read access to the default namespace. 106 defaultNamespacePolicy := api.ACLPolicy{ 107 Name: "e2e-acl-" + uuid.Short(), 108 Description: "E2E ACL Role Testing", 109 Rules: `namespace "default" {policy = "read"}`, 110 } 111 _, err = nomadClient.ACLPolicies().Upsert(&defaultNamespacePolicy, nil) 112 require.NoError(t, err) 113 114 cleanUpProcess.add(defaultNamespacePolicy.Name, aclPolicyTestResourceType) 115 116 // Update the ACL role to include the new ACL policy that allows read 117 // access to the default namespace. 118 aclRoleCreateResp.Policies = append(aclRoleCreateResp.Policies, &api.ACLRolePolicyLink{ 119 Name: defaultNamespacePolicy.Name, 120 }) 121 aclRoleUpdateResp, _, err := nomadClient.ACLRoles().Update(aclRoleCreateResp, nil) 122 require.NoError(t, err) 123 require.Equal(t, aclRoleCreateResp.ID, aclRoleUpdateResp.ID) 124 require.Len(t, aclRoleUpdateResp.Policies, 2) 125 126 // Try listing the jobs in the default namespace again to ensure we now 127 // have permission due to the updated role. 128 jobListResp, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta) 129 require.NoError(t, err) 130 require.Empty(t, jobListResp) 131 132 // Delete a policy from under the role. 133 _, err = nomadClient.ACLPolicies().Delete(defaultNamespacePolicy.Name, nil) 134 require.NoError(t, err) 135 136 cleanUpProcess.remove(defaultNamespacePolicy.Name, aclPolicyTestResourceType) 137 138 // The permission to list the job in the default namespace should now be 139 // revoked. 140 jobListResp, _, err = nomadClient.Jobs().List(&defaultNSQueryMeta) 141 require.ErrorContains(t, err, "Permission denied") 142 143 // Delete the ACL role. 144 _, err = nomadClient.ACLRoles().Delete(aclRoleUpdateResp.ID, nil) 145 require.NoError(t, err) 146 147 cleanUpProcess.remove(aclRoleUpdateResp.ID, aclRoleTestResourceType) 148 149 // We should now not be able to list jobs in the custom namespace either as 150 // the token does not have any permissions. 151 jobListResp, _, err = nomadClient.Jobs().List(&customNSQueryMeta) 152 require.ErrorContains(t, err, "Permission denied") 153 }