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