github.com/adityamillind98/nomad@v0.11.8/nomad/search_endpoint_oss.go (about) 1 // +build !ent 2 3 package nomad 4 5 import ( 6 "fmt" 7 8 memdb "github.com/hashicorp/go-memdb" 9 "github.com/hashicorp/nomad/acl" 10 "github.com/hashicorp/nomad/nomad/state" 11 "github.com/hashicorp/nomad/nomad/structs" 12 ) 13 14 var ( 15 // allContexts are the available contexts which are searched to find matches 16 // for a given prefix 17 allContexts = ossContexts 18 ) 19 20 // contextToIndex returns the index name to lookup in the state store. 21 func contextToIndex(ctx structs.Context) string { 22 return string(ctx) 23 } 24 25 // getEnterpriseMatch is a no-op in oss since there are no enterprise objects. 26 func getEnterpriseMatch(match interface{}) (id string, ok bool) { 27 return "", false 28 } 29 30 // getEnterpriseResourceIter is used to retrieve an iterator over an enterprise 31 // only table. 32 func getEnterpriseResourceIter(context structs.Context, _ *acl.ACL, namespace, prefix string, ws memdb.WatchSet, state *state.StateStore) (memdb.ResultIterator, error) { 33 // If we have made it here then it is an error since we have exhausted all 34 // open source contexts. 35 return nil, fmt.Errorf("context must be one of %v or 'all' for all contexts; got %q", allContexts, context) 36 } 37 38 // anySearchPerms returns true if the provided ACL has access to any 39 // capabilities required for prefix searching. Returns true if aclObj is nil. 40 func anySearchPerms(aclObj *acl.ACL, namespace string, context structs.Context) bool { 41 if aclObj == nil { 42 return true 43 } 44 45 nodeRead := aclObj.AllowNodeRead() 46 jobRead := aclObj.AllowNsOp(namespace, acl.NamespaceCapabilityReadJob) 47 allowVolume := acl.NamespaceValidator(acl.NamespaceCapabilityCSIListVolume, 48 acl.NamespaceCapabilityCSIReadVolume, 49 acl.NamespaceCapabilityListJobs, 50 acl.NamespaceCapabilityReadJob) 51 volRead := allowVolume(aclObj, namespace) 52 53 if !nodeRead && !jobRead && !volRead { 54 return false 55 } 56 57 // Reject requests that explicitly specify a disallowed context. This 58 // should give the user better feedback then simply filtering out all 59 // results and returning an empty list. 60 if !nodeRead && context == structs.Nodes { 61 return false 62 } 63 if !jobRead { 64 switch context { 65 case structs.Allocs, structs.Deployments, structs.Evals, structs.Jobs: 66 return false 67 } 68 } 69 if !volRead && context == structs.Volumes { 70 return false 71 } 72 73 return true 74 } 75 76 // searchContexts returns the contexts the aclObj is valid for. If aclObj is 77 // nil all contexts are returned. 78 func searchContexts(aclObj *acl.ACL, namespace string, context structs.Context) []structs.Context { 79 var all []structs.Context 80 81 switch context { 82 case structs.All: 83 all = make([]structs.Context, len(allContexts)) 84 copy(all, allContexts) 85 default: 86 all = []structs.Context{context} 87 } 88 89 // If ACLs aren't enabled return all contexts 90 if aclObj == nil { 91 return all 92 } 93 94 jobRead := aclObj.AllowNsOp(namespace, acl.NamespaceCapabilityReadJob) 95 allowVolume := acl.NamespaceValidator(acl.NamespaceCapabilityCSIListVolume, 96 acl.NamespaceCapabilityCSIReadVolume, 97 acl.NamespaceCapabilityListJobs, 98 acl.NamespaceCapabilityReadJob) 99 volRead := allowVolume(aclObj, namespace) 100 101 // Filter contexts down to those the ACL grants access to 102 available := make([]structs.Context, 0, len(all)) 103 for _, c := range all { 104 switch c { 105 case structs.Allocs, structs.Jobs, structs.Evals, structs.Deployments: 106 if jobRead { 107 available = append(available, c) 108 } 109 case structs.Nodes: 110 if aclObj.AllowNodeRead() { 111 available = append(available, c) 112 } 113 case structs.Volumes: 114 if volRead { 115 available = append(available, c) 116 } 117 } 118 } 119 return available 120 }