Apache Mesos
http.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __COMMON_HTTP_HPP__
18 #define __COMMON_HTTP_HPP__
19 
20 #include <vector>
21 
22 #include <mesos/http.hpp>
23 #include <mesos/mesos.hpp>
24 
26 
27 #include <mesos/quota/quota.hpp>
28 
29 #include <process/future.hpp>
30 #include <process/http.hpp>
31 #include <process/owned.hpp>
32 
33 #include <stout/hashmap.hpp>
34 #include <stout/hashset.hpp>
35 #include <stout/json.hpp>
36 #include <stout/jsonify.hpp>
37 #include <stout/protobuf.hpp>
38 #include <stout/unreachable.hpp>
39 
40 namespace mesos {
41 
42 class Attributes;
43 class Resources;
44 class Task;
45 
46 namespace internal {
47 
48 // Name of the default, basic authenticator.
49 constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATOR[] = "basic";
50 
51 // Name of the default, basic authenticatee.
52 constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATEE[] = "basic";
53 
54 // Name of the default, JWT authenticator.
55 constexpr char DEFAULT_JWT_HTTP_AUTHENTICATOR[] = "jwt";
56 
58 
59 
60 // Contains the media types corresponding to some of the "Content-*",
61 // "Accept-*" and "Message-*" prefixed request headers in our internal
62 // representation.
64 {
65  ContentType content; // 'Content-Type' header.
66  ContentType accept; // 'Accept' header.
67  Option<ContentType> messageContent; // 'Message-Content-Type' header.
68  Option<ContentType> messageAccept; // 'Message-Accept' header.
69 };
70 
71 
72 // Serializes a protobuf message for transmission
73 // based on the HTTP content type.
74 // NOTE: For streaming `contentType`, `message` would not
75 // be serialized in "Record-IO" format.
76 std::string serialize(
77  ContentType contentType,
78  const google::protobuf::Message& message);
79 
80 
81 // Deserializes a string message into a protobuf message based on the
82 // HTTP content type.
83 template <typename Message>
85  ContentType contentType,
86  const std::string& body)
87 {
88  switch (contentType) {
89  case ContentType::PROTOBUF: {
90  Message message;
91  if (!message.ParseFromString(body)) {
92  return Error("Failed to parse body into a protobuf object");
93  }
94  return message;
95  }
96  case ContentType::JSON: {
97  Try<JSON::Value> value = JSON::parse(body);
98  if (value.isError()) {
99  return Error("Failed to parse body into JSON: " + value.error());
100  }
101 
102  return ::protobuf::parse<Message>(value.get());
103  }
104  case ContentType::RECORDIO: {
105  return Error("Deserializing a RecordIO stream is not supported");
106  }
107  }
108 
109  UNREACHABLE();
110 }
111 
112 
113 // Returns true if the media type can be used for
114 // streaming requests/responses.
115 bool streamingMediaType(ContentType contentType);
116 
117 
118 JSON::Object model(const Resources& resources);
120 JSON::Object model(const Attributes& attributes);
121 JSON::Object model(const CommandInfo& command);
122 JSON::Object model(const ExecutorInfo& executorInfo);
123 JSON::Array model(const Labels& labels);
124 JSON::Object model(const Task& task);
125 JSON::Object model(const FileInfo& fileInfo);
126 JSON::Object model(const quota::QuotaInfo& quotaInfo);
127 
128 void json(JSON::ObjectWriter* writer, const Task& task);
129 
130 } // namespace internal {
131 
132 void json(JSON::ObjectWriter* writer, const Attributes& attributes);
133 void json(JSON::ObjectWriter* writer, const CommandInfo& command);
134 void json(JSON::ObjectWriter* writer, const ExecutorInfo& executorInfo);
135 void json(JSON::ArrayWriter* writer, const Labels& labels);
136 void json(JSON::ObjectWriter* writer, const Resources& resources);
137 void json(JSON::ObjectWriter* writer, const Task& task);
138 void json(JSON::ObjectWriter* writer, const TaskStatus& status);
139 void json(JSON::ObjectWriter* writer, const DomainInfo& domainInfo);
140 
141 namespace authorization {
142 
143 // Creates a subject for authorization purposes when given an authenticated
144 // principal. This function accepts and returns an `Option` to make call sites
145 // cleaner, since it is possible that `principal` will be `NONE`.
148 
149 } // namespace authorization {
150 
153 
154 
155 // Implementation of the `ObjectApprover` interface authorizing all objects.
157 {
158 public:
160  const Option<ObjectApprover::Object>& object) const noexcept override
161  {
162  return true;
163  }
164 };
165 
166 
167 // Determines which objects will be accepted based on authorization.
169 {
170 public:
173  const Option<Authorizer*>& authorizer,
174  const authorization::Action& action);
175 
176  template <typename... Args>
177  bool accept(Args&... args)
178  {
179  Try<bool> approved =
180  objectApprover->approved(ObjectApprover::Object(args...));
181  if (approved.isError()) {
182  LOG(WARNING) << "Error during authorization: " << approved.error();
183  return false;
184  }
185 
186  return approved.get();
187  }
188 
189 protected:
190  // TODO(qleng): Currently, `Owned` is implemented with `shared_ptr` and allows
191  // copying. In the future, if `Owned` is implemented with `unique_ptr`, we
192  // will need to pass by rvalue reference here instead (see MESOS-5122).
194  : objectApprover(approver) {}
195 
197 };
198 
199 
205 template <typename T>
207 {
208 public:
209  IDAcceptor(const Option<std::string>& id = None())
210  {
211  if (id.isSome()) {
212  T targetId_;
213  targetId_.set_value(id.get());
214  targetId = targetId_;
215  }
216  }
217 
218  bool accept(const T& candidateId) const
219  {
220  if (targetId.isNone()) {
221  return true;
222  }
223 
224  return candidateId.value() == targetId->value();
225  }
226 
227 protected:
228  Option<T> targetId;
229 };
230 
231 
233  const process::Owned<ObjectApprover>& frameworksApprover,
234  const FrameworkInfo& frameworkInfo);
235 
236 
238  const process::Owned<ObjectApprover>& executorsApprover,
239  const ExecutorInfo& executorInfo,
240  const FrameworkInfo& frameworkInfo);
241 
242 
244  const process::Owned<ObjectApprover>& tasksApprover,
245  const TaskInfo& taskInfo,
246  const FrameworkInfo& frameworkInfo);
247 
248 
249 bool approveViewTask(
250  const process::Owned<ObjectApprover>& tasksApprover,
251  const Task& task,
252  const FrameworkInfo& frameworkInfo);
253 
254 
255 bool approveViewFlags(const process::Owned<ObjectApprover>& flagsApprover);
256 
257 
258 // Authorizes access to an HTTP endpoint. The `method` parameter
259 // determines which ACL action will be used in the authorization.
260 // It is expected that the caller has validated that `method` is
261 // supported by this function. Currently "GET" is supported.
262 //
263 // TODO(nfnt): Prefer types instead of strings
264 // for `endpoint` and `method`, see MESOS-5300.
266  const std::string& endpoint,
267  const std::string& method,
268  const Option<Authorizer*>& authorizer,
270 
271 
272 bool approveViewRole(
273  const process::Owned<ObjectApprover>& rolesApprover,
274  const std::string& role);
275 
276 // Authorizes resources in either the pre- or the post-reservation-refinement
277 // formats.
278 // TODO(arojas): Update this helper to only accept the
279 // post-reservation-refinement format once MESOS-7851 is resolved.
280 bool authorizeResource(
281  const Resource& resource,
283 
284 
298  const std::string& realm,
299  const std::vector<std::string>& httpAuthenticatorNames,
300  const Option<Credentials>& credentials = None(),
301  const Option<std::string>& jwtSecretKey = None());
302 
303 
304 // Logs the request. Route handlers can compose this with the
305 // desired request handler to get consistent request logging.
307 
308 } // namespace mesos {
309 
310 #endif // __COMMON_HTTP_HPP__
bool approveViewTask(const process::Owned< ObjectApprover > &tasksApprover, const Task &task, const FrameworkInfo &frameworkInfo)
Definition: http.hpp:156
ContentType accept
Definition: http.hpp:66
ContentType
Definition: http.hpp:43
Definition: errorbase.hpp:35
virtual Try< bool > approved(const Option< ObjectApprover::Object > &object) const noexceptoverride
NOTE: As this function can be used synchronously by actors it is essential that it does not block! ...
Definition: http.hpp:159
Future< Response > request(const Request &request, bool streamedResponse=false)
Asynchronously sends an HTTP request to the process and returns the HTTP response once the entire res...
const Option< authorization::Subject > createSubject(const Option< process::http::authentication::Principal > &principal)
Definition: authorizer.hpp:46
Definition: try.hpp:34
bool streamingMediaType(ContentType contentType)
const process::Owned< ObjectApprover > objectApprover
Definition: http.hpp:196
bool accept(Args &...args)
Definition: http.hpp:177
constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATEE[]
Definition: http.hpp:52
Result< ProcessStatus > status(pid_t pid)
Definition: proc.hpp:166
Definition: resources.hpp:79
Definition: json.hpp:194
Definition: http.hpp:518
Definition: json.hpp:154
Definition: hashmap.hpp:38
constexpr char DEFAULT_JWT_HTTP_AUTHENTICATOR[]
Definition: http.hpp:55
This interface is used to enable an identity service or any other back end to check authorization pol...
Definition: authorizer.hpp:243
void logRequest(const process::http::Request &request)
Used to filter results for API handlers.
Definition: http.hpp:206
Try< Message > deserialize(ContentType contentType, const std::string &body)
Definition: http.hpp:84
bool approveViewExecutorInfo(const process::Owned< ObjectApprover > &executorsApprover, const ExecutorInfo &executorInfo, const FrameworkInfo &frameworkInfo)
Definition: http.hpp:63
bool approveViewFlags(const process::Owned< ObjectApprover > &flagsApprover)
JSON::Object model(const Resources &resources)
void json(JSON::ObjectWriter *writer, const Task &task)
Definition: jsonify.hpp:418
Option< Error > quotaInfo(const mesos::quota::QuotaInfo &quotaInfo)
hashset< std::string > AUTHORIZABLE_ENDPOINTS
Try< Value > parse(const std::string &s)
Returns the OCI v1 descriptor, image index, image manifest and image configuration from the given str...
Definition: json.hpp:886
ContentType content
Definition: http.hpp:65
Try< int_fd > accept(int_fd s)
Definition: network.hpp:31
Option< ContentType > messageContent
Definition: http.hpp:67
static Try error(const E &e)
Definition: try.hpp:42
Try< Nothing > initializeHttpAuthenticators(const std::string &realm, const std::vector< std::string > &httpAuthenticatorNames, const Option< Credentials > &credentials=None(), const Option< std::string > &jwtSecretKey=None())
Helper function to create HTTP authenticators for a given realm and register in libprocess.
#define UNREACHABLE()
Definition: unreachable.hpp:22
void json(JSON::ObjectWriter *writer, const Attributes &attributes)
const process::http::authorization::AuthorizationCallbacks createAuthorizationCallbacks(Authorizer *authorizer)
constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATOR[]
Definition: http.hpp:49
bool authorizeResource(const Resource &resource, const Option< process::Owned< AuthorizationAcceptor >> &acceptor)
bool approveViewFrameworkInfo(const process::Owned< ObjectApprover > &frameworksApprover, const FrameworkInfo &frameworkInfo)
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:71
Option< ContentType > messageAccept
Definition: http.hpp:68
bool approveViewRole(const process::Owned< ObjectApprover > &rolesApprover, const std::string &role)
std::string serialize(ContentType contentType, const google::protobuf::Message &message)
process::Future< bool > authorizeEndpoint(const std::string &endpoint, const std::string &method, const Option< Authorizer * > &authorizer, const Option< process::http::authentication::Principal > &principal)
This interface represents a function object returned by the authorizer which can be used locally (and...
Definition: authorizer.hpp:40
Definition: owned.hpp:35
Definition: http.hpp:168
const T & get() const
Definition: try.hpp:73
static process::Future< process::Owned< AuthorizationAcceptor > > create(const Option< process::http::authentication::Principal > &principal, const Option< Authorizer * > &authorizer, const authorization::Action &action)
AuthorizationAcceptor(const process::Owned< ObjectApprover > &approver)
Definition: http.hpp:193
bool approveViewTaskInfo(const process::Owned< ObjectApprover > &tasksApprover, const TaskInfo &taskInfo, const FrameworkInfo &frameworkInfo)
Definition: jsonify.hpp:384
Definition: future.hpp:57
Definition: attributes.hpp:32