github.com/rohankumardubey/nomad@v0.11.8/command/agent/acl_endpoint.go (about) 1 package agent 2 3 import ( 4 "net/http" 5 "strings" 6 7 "github.com/hashicorp/nomad/nomad/structs" 8 ) 9 10 func (s *HTTPServer) ACLPoliciesRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 11 if req.Method != "GET" { 12 return nil, CodedError(405, ErrInvalidMethod) 13 } 14 15 args := structs.ACLPolicyListRequest{} 16 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 17 return nil, nil 18 } 19 20 var out structs.ACLPolicyListResponse 21 if err := s.agent.RPC("ACL.ListPolicies", &args, &out); err != nil { 22 return nil, err 23 } 24 25 setMeta(resp, &out.QueryMeta) 26 if out.Policies == nil { 27 out.Policies = make([]*structs.ACLPolicyListStub, 0) 28 } 29 return out.Policies, nil 30 } 31 32 func (s *HTTPServer) ACLPolicySpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 33 name := strings.TrimPrefix(req.URL.Path, "/v1/acl/policy/") 34 if len(name) == 0 { 35 return nil, CodedError(400, "Missing Policy Name") 36 } 37 switch req.Method { 38 case "GET": 39 return s.aclPolicyQuery(resp, req, name) 40 case "PUT", "POST": 41 return s.aclPolicyUpdate(resp, req, name) 42 case "DELETE": 43 return s.aclPolicyDelete(resp, req, name) 44 default: 45 return nil, CodedError(405, ErrInvalidMethod) 46 } 47 } 48 49 func (s *HTTPServer) aclPolicyQuery(resp http.ResponseWriter, req *http.Request, 50 policyName string) (interface{}, error) { 51 args := structs.ACLPolicySpecificRequest{ 52 Name: policyName, 53 } 54 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 55 return nil, nil 56 } 57 58 var out structs.SingleACLPolicyResponse 59 if err := s.agent.RPC("ACL.GetPolicy", &args, &out); err != nil { 60 return nil, err 61 } 62 63 setMeta(resp, &out.QueryMeta) 64 if out.Policy == nil { 65 return nil, CodedError(404, "ACL policy not found") 66 } 67 return out.Policy, nil 68 } 69 70 func (s *HTTPServer) aclPolicyUpdate(resp http.ResponseWriter, req *http.Request, 71 policyName string) (interface{}, error) { 72 // Parse the policy 73 var policy structs.ACLPolicy 74 if err := decodeBody(req, &policy); err != nil { 75 return nil, CodedError(500, err.Error()) 76 } 77 78 // Ensure the policy name matches 79 if policy.Name != policyName { 80 return nil, CodedError(400, "ACL policy name does not match request path") 81 } 82 83 // Format the request 84 args := structs.ACLPolicyUpsertRequest{ 85 Policies: []*structs.ACLPolicy{&policy}, 86 } 87 s.parseWriteRequest(req, &args.WriteRequest) 88 89 var out structs.GenericResponse 90 if err := s.agent.RPC("ACL.UpsertPolicies", &args, &out); err != nil { 91 return nil, err 92 } 93 setIndex(resp, out.Index) 94 return nil, nil 95 } 96 97 func (s *HTTPServer) aclPolicyDelete(resp http.ResponseWriter, req *http.Request, 98 policyName string) (interface{}, error) { 99 100 args := structs.ACLPolicyDeleteRequest{ 101 Names: []string{policyName}, 102 } 103 s.parseWriteRequest(req, &args.WriteRequest) 104 105 var out structs.GenericResponse 106 if err := s.agent.RPC("ACL.DeletePolicies", &args, &out); err != nil { 107 return nil, err 108 } 109 setIndex(resp, out.Index) 110 return nil, nil 111 } 112 113 func (s *HTTPServer) ACLTokensRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 114 if req.Method != "GET" { 115 return nil, CodedError(405, ErrInvalidMethod) 116 } 117 118 args := structs.ACLTokenListRequest{} 119 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 120 return nil, nil 121 } 122 123 var out structs.ACLTokenListResponse 124 if err := s.agent.RPC("ACL.ListTokens", &args, &out); err != nil { 125 return nil, err 126 } 127 128 setMeta(resp, &out.QueryMeta) 129 if out.Tokens == nil { 130 out.Tokens = make([]*structs.ACLTokenListStub, 0) 131 } 132 return out.Tokens, nil 133 } 134 135 func (s *HTTPServer) ACLTokenBootstrap(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 136 // Ensure this is a PUT or POST 137 if !(req.Method == "PUT" || req.Method == "POST") { 138 return nil, CodedError(405, ErrInvalidMethod) 139 } 140 141 // Format the request 142 args := structs.ACLTokenBootstrapRequest{} 143 s.parseWriteRequest(req, &args.WriteRequest) 144 145 var out structs.ACLTokenUpsertResponse 146 if err := s.agent.RPC("ACL.Bootstrap", &args, &out); err != nil { 147 return nil, err 148 } 149 setIndex(resp, out.Index) 150 if len(out.Tokens) > 0 { 151 return out.Tokens[0], nil 152 } 153 return nil, nil 154 } 155 156 func (s *HTTPServer) ACLTokenSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 157 path := req.URL.Path 158 159 switch path { 160 case "/v1/acl/token": 161 if !(req.Method == "PUT" || req.Method == "POST") { 162 return nil, CodedError(405, ErrInvalidMethod) 163 } 164 return s.aclTokenUpdate(resp, req, "") 165 case "/v1/acl/token/self": 166 return s.aclTokenSelf(resp, req) 167 } 168 169 accessor := strings.TrimPrefix(path, "/v1/acl/token/") 170 return s.aclTokenCrud(resp, req, accessor) 171 } 172 173 func (s *HTTPServer) aclTokenCrud(resp http.ResponseWriter, req *http.Request, 174 tokenAccessor string) (interface{}, error) { 175 if tokenAccessor == "" { 176 return nil, CodedError(400, "Missing Token Accessor") 177 } 178 179 switch req.Method { 180 case "GET": 181 return s.aclTokenQuery(resp, req, tokenAccessor) 182 case "PUT", "POST": 183 return s.aclTokenUpdate(resp, req, tokenAccessor) 184 case "DELETE": 185 return s.aclTokenDelete(resp, req, tokenAccessor) 186 default: 187 return nil, CodedError(405, ErrInvalidMethod) 188 } 189 } 190 191 func (s *HTTPServer) aclTokenQuery(resp http.ResponseWriter, req *http.Request, 192 tokenAccessor string) (interface{}, error) { 193 args := structs.ACLTokenSpecificRequest{ 194 AccessorID: tokenAccessor, 195 } 196 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 197 return nil, nil 198 } 199 200 var out structs.SingleACLTokenResponse 201 if err := s.agent.RPC("ACL.GetToken", &args, &out); err != nil { 202 return nil, err 203 } 204 205 setMeta(resp, &out.QueryMeta) 206 if out.Token == nil { 207 return nil, CodedError(404, "ACL token not found") 208 } 209 return out.Token, nil 210 } 211 212 func (s *HTTPServer) aclTokenSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 213 if req.Method != "GET" { 214 return nil, CodedError(405, ErrInvalidMethod) 215 } 216 args := structs.ResolveACLTokenRequest{} 217 if s.parse(resp, req, &args.Region, &args.QueryOptions) { 218 return nil, nil 219 } 220 221 args.SecretID = args.AuthToken 222 223 var out structs.ResolveACLTokenResponse 224 if err := s.agent.RPC("ACL.ResolveToken", &args, &out); err != nil { 225 return nil, err 226 } 227 228 setMeta(resp, &out.QueryMeta) 229 if out.Token == nil { 230 return nil, CodedError(404, "ACL token not found") 231 } 232 return out.Token, nil 233 } 234 235 func (s *HTTPServer) aclTokenUpdate(resp http.ResponseWriter, req *http.Request, 236 tokenAccessor string) (interface{}, error) { 237 // Parse the token 238 var token structs.ACLToken 239 if err := decodeBody(req, &token); err != nil { 240 return nil, CodedError(500, err.Error()) 241 } 242 243 // Ensure the token accessor matches 244 if tokenAccessor != "" && (token.AccessorID != tokenAccessor) { 245 return nil, CodedError(400, "ACL token accessor does not match request path") 246 } 247 248 // Format the request 249 args := structs.ACLTokenUpsertRequest{ 250 Tokens: []*structs.ACLToken{&token}, 251 } 252 s.parseWriteRequest(req, &args.WriteRequest) 253 254 var out structs.ACLTokenUpsertResponse 255 if err := s.agent.RPC("ACL.UpsertTokens", &args, &out); err != nil { 256 return nil, err 257 } 258 setIndex(resp, out.Index) 259 if len(out.Tokens) > 0 { 260 return out.Tokens[0], nil 261 } 262 return nil, nil 263 } 264 265 func (s *HTTPServer) aclTokenDelete(resp http.ResponseWriter, req *http.Request, 266 tokenAccessor string) (interface{}, error) { 267 268 args := structs.ACLTokenDeleteRequest{ 269 AccessorIDs: []string{tokenAccessor}, 270 } 271 s.parseWriteRequest(req, &args.WriteRequest) 272 273 var out structs.GenericResponse 274 if err := s.agent.RPC("ACL.DeleteTokens", &args, &out); err != nil { 275 return nil, err 276 } 277 setIndex(resp, out.Index) 278 return nil, nil 279 }