Apache Mesos
validation.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 __MASTER_VALIDATION_HPP__
18 #define __MASTER_VALIDATION_HPP__
19 
20 #include <vector>
21 
22 #include <google/protobuf/repeated_field.h>
23 
24 #include <mesos/mesos.hpp>
25 #include <mesos/resources.hpp>
26 
28 
29 #include <mesos/master/master.hpp>
30 
32 
33 #include <stout/error.hpp>
34 #include <stout/option.hpp>
35 
37 
38 namespace mesos {
39 namespace internal {
40 namespace master {
41 
42 class Master;
43 
44 struct Framework;
45 struct Slave;
46 
47 namespace validation {
48 
49 namespace master {
50 namespace call {
51 
52 // Validates that a master:Call is well-formed.
53 //
54 // TODO(bmahler): Note that this does not validate the fields within
55 // the nested messages (e.g. `ReserveResources`) which is unintuitive.
56 // Consider moving all `master::Call` validation that does not require
57 // master state into this function.
58 //
59 // TODO(bmahler): Add unit tests.
61 
62 } // namespace call {
63 
64 namespace message {
65 
66 // Validation helpers for internal Mesos protocol messages. This is a
67 // best-effort validation, intended to prevent trivial attacks on the
68 // protocol in deployments where the network between master and agents
69 // is not secured. The longer term remedy for this is to make security
70 // guarantees at the libprocess level that would prevent arbitrary UPID
71 // impersonation (MESOS-7424).
72 
73 Option<Error> registerSlave(const RegisterSlaveMessage& message);
74 Option<Error> reregisterSlave(const ReregisterSlaveMessage& message);
75 
76 } // namespace message {
77 } // namespace master {
78 
79 
80 namespace framework {
81 namespace internal {
82 
83 // Validates the roles in given FrameworkInfo. Role, roles and
84 // MULTI_ROLE should be set according to following matrix. Also,
85 // roles should not contain duplicate entries.
86 //
87 // -- MULTI_ROLE is NOT set --
88 // +-------+-------+---------+
89 // | |Roles |No Roles |
90 // +-------+-------+---------+
91 // |Role | Error | None |
92 // +-------+-------+---------+
93 // |No Role| Error | None |
94 // +-------+-------+---------+
95 //
96 // ---- MULTI_ROLE is set ----
97 // +-------+-------+---------+
98 // | |Roles |No Roles |
99 // +-------+-------+---------+
100 // |Role | Error | Error |
101 // +-------+-------+---------+
102 // |No Role| None | None |
103 // +-------+-------+---------+
104 Option<Error> validateRoles(const mesos::FrameworkInfo& frameworkInfo);
105 
106 Option<Error> validateFrameworkId(const mesos::FrameworkInfo& frameworkInfo);
107 
108 Option<Error> validateOfferFilters(const FrameworkInfo& frameworkInfo);
109 
110 } // namespace internal {
111 
112 // Validate a FrameworkInfo.
113 Option<Error> validate(const mesos::FrameworkInfo& frameworkInfo);
114 
115 // Validate that the immutable fields of two FrameworkInfos are identical.
116 // Currently these fields are 'principal', 'user' and 'checkpoint'.
118  const FrameworkInfo& oldInfo,
119  const FrameworkInfo& newInfo);
120 
121 // Adjusts `newInfo` to ensure that the `user` and `checkpoint` fields
122 // are not modified and logs a warning if they were modified.
123 //
124 // NOTE: This is a legacy function used to preserve the behavior of
125 // re-subscription silently ignoring these fields. It should not be
126 // used in new code.
127 //
128 // TODO(asekretenko): Remove this function (see MESOS-9747).
130  const FrameworkInfo& oldInfo,
131  FrameworkInfo* newInfo);
132 
134  const std::set<std::string>& validFrameworkRoles,
135  const std::set<std::string>& suppressedRoles);
136 
138  const std::set<std::string>& validFrameworkRoles,
139  const scheduler::OfferConstraints& offerConstraints);
140 
141 } // namespace framework {
142 
143 
144 namespace scheduler {
145 namespace call {
146 
147 // Validates that a scheduler::Call is well-formed.
148 // TODO(bmahler): Add unit tests.
150  const mesos::scheduler::Call& call,
152 
153 } // namespace call {
154 } // namespace scheduler {
155 
156 
157 namespace resource {
158 
159 // Functions in this namespace are only exposed for testing.
160 namespace internal {
161 
163  const google::protobuf::RepeatedPtrField<Resource>& resources);
164 
165 } // namespace internal {
166 
167 // Returns `true` if there is any overlap between set- or range-valued
168 // resources in the provided `Resources` objects.
170  const std::vector<Resources>& resources);
171 
172 // Validates resources specified by frameworks.
173 // NOTE: We cannot take 'Resources' here because invalid resources are
174 // silently ignored within its constructor.
176  const google::protobuf::RepeatedPtrField<Resource>& resources);
177 
178 } // namespace resource {
179 
180 
181 namespace executor {
182 
183 // Functions in this namespace are only exposed for testing.
184 namespace internal {
185 
186 Option<Error> validateExecutorID(const ExecutorInfo& executor);
187 
188 // Validates that fields are properly set depending on the type of the executor.
189 Option<Error> validateType(const ExecutorInfo& executor);
190 
191 // Validates resources of the executor.
192 Option<Error> validateResources(const ExecutorInfo& executor);
193 
194 } // namespace internal {
195 
196 Option<Error> validate(const ExecutorInfo& executor);
197 
198 } // namespace executor {
199 
200 
201 namespace task {
202 
203 // Validates a task that a framework attempts to launch within the
204 // offered resources. Returns an optional error which will cause the
205 // master to send a `TASK_ERROR` status update back to the framework.
206 //
207 // NOTE: This function must be called sequentially for each task, and
208 // each task needs to be launched before the next can be validated.
210  const TaskInfo& task,
211  Framework* framework,
212  Slave* slave,
213  const Resources& offered);
214 
215 
216 // Functions in this namespace are only exposed for testing.
217 namespace internal {
218 
219 // Validates resources of the task.
220 Option<Error> validateResources(const TaskInfo& task);
221 
222 // Validates resources of the task and its executor.
223 Option<Error> validateTaskAndExecutorResources(const TaskInfo& task);
224 
225 // Validates the kill policy of the task.
226 Option<Error> validateKillPolicy(const TaskInfo& task);
227 
228 // Validates `max_completion_time` of the task.
229 Option<Error> validateMaxCompletionTime(const TaskInfo& task);
230 
231 // Validates the check of the task.
232 Option<Error> validateCheck(const TaskInfo& task);
233 
234 // Validates the health check of the task.
235 Option<Error> validateHealthCheck(const TaskInfo& task);
236 
237 } // namespace internal {
238 
239 namespace group {
240 
241 // Validates a task group that a framework attempts to launch within the
242 // offered resources. Returns an optional error which will cause the
243 // master to send a `TASK_ERROR` status updates for *all* the tasks in
244 // the task group back to the framework.
245 //
246 // NOTE: Validation error of *any* task will cause all the tasks in the task
247 // group to be rejected by the master.
249  const TaskGroupInfo& taskGroup,
250  const ExecutorInfo& executor,
251  Framework* framework,
252  Slave* slave,
253  const Resources& offered);
254 
255 
256 // Functions in this namespace are only exposed for testing.
257 namespace internal {
258 
259 // Validates that the resources specified by
260 // the task group and its executor are valid.
261 //
262 // TODO(vinod): Consolidate this with `validateTaskAndExecutorResources()`.
264  const TaskGroupInfo& taskGroup,
265  const ExecutorInfo& executor);
266 
267 } // namespace internal {
268 
269 } // namespace group {
270 
271 } // namespace task {
272 
273 
274 namespace offer {
275 
276 // NOTE: These two functions are placed in the header file because we
277 // need to declare them as friends of Master.
278 Offer* getOffer(Master* master, const OfferID& offerId);
279 InverseOffer* getInverseOffer(Master* master, const OfferID& offerId);
280 Slave* getSlave(Master* master, const SlaveID& slaveId);
281 
282 
283 // Validates the given offers.
285  const google::protobuf::RepeatedPtrField<OfferID>& offerIds,
286  Master* master,
287  Framework* framework);
288 
289 
290 // Validates the given inverse offers.
292  const google::protobuf::RepeatedPtrField<OfferID>& offerIds,
293  Master* master,
294  Framework* framework);
295 
296 } // namespace offer {
297 
298 
299 namespace operation {
300 
301 // Validates the RESERVE operation.
303  const Offer::Operation::Reserve& reserve,
305  const protobuf::slave::Capabilities& agentCapabilities,
306  const Option<FrameworkInfo>& frameworkInfo = None());
307 
308 
309 // Validates the UNRESERVE operation.
311  const Offer::Operation::Unreserve& unreserve,
312  const Option<FrameworkInfo>& frameworkInfo = None());
313 
314 
315 // Validates the CREATE operation. We need slave's checkpointed resources so
316 // that we can validate persistence ID uniqueness, and we need the principal to
317 // verify that it's equal to the one in `DiskInfo.Persistence.principal`.
318 // We need the FrameworkInfo (unless the operation is requested by the
319 // operator) to ensure shared volumes are created by frameworks with the
320 // appropriate capability.
322  const Offer::Operation::Create& create,
323  const Resources& checkpointedResources,
325  const protobuf::slave::Capabilities& agentCapabilities,
326  const Option<FrameworkInfo>& frameworkInfo = None());
327 
328 
329 // Validates the DESTROY operation. We need slave's checkpointed
330 // resources to validate that the volumes to destroy actually exist.
331 // We also check that the volumes are not being used, or not assigned
332 // to any pending task.
334  const Offer::Operation::Destroy& destroy,
335  const Resources& checkpointedResources,
336  const hashmap<FrameworkID, Resources>& usedResources,
337  const Option<FrameworkInfo>& frameworkInfo = None());
338 
339 
341  const Offer::Operation::GrowVolume& growVolume,
342  const protobuf::slave::Capabilities& agentCapabilities);
343 
344 
346  const Offer::Operation::ShrinkVolume& shrinkVolume,
347  const protobuf::slave::Capabilities& agentCapabilities);
348 
349 
350 Option<Error> validate(const Offer::Operation::CreateDisk& createDisk);
351 
352 
353 Option<Error> validate(const Offer::Operation::DestroyDisk& destroyDisk);
354 
355 } // namespace operation {
356 
357 } // namespace validation {
358 } // namespace master {
359 } // namespace internal {
360 } // namespace mesos {
361 
362 #endif // __MASTER_VALIDATION_HPP__
Option< Error > validateExecutorID(const ExecutorInfo &executor)
Option< Error > validateFrameworkId(const mesos::FrameworkInfo &frameworkInfo)
Definition: master.hpp:27
Option< Error > validateMaxCompletionTime(const TaskInfo &task)
Definition: protobuf_utils.hpp:332
Option< Error > validateSuppressedRoles(const std::set< std::string > &validFrameworkRoles, const std::set< std::string > &suppressedRoles)
InverseOffer * getInverseOffer(Master *master, const OfferID &offerId)
mesos::v1::scheduler::Call Call
Definition: mesos.hpp:2851
Definition: resources.hpp:83
Slave * getSlave(Master *master, const SlaveID &slaveId)
Option< Error > validateResources(const TaskInfo &task)
Option< Error > reregisterSlave(const ReregisterSlaveMessage &message)
Definition: hashmap.hpp:38
Option< Error > validateUpdate(const FrameworkInfo &oldInfo, const FrameworkInfo &newInfo)
Option< Error > validateInverseOffers(const google::protobuf::RepeatedPtrField< OfferID > &offerIds, Master *master, Framework *framework)
Option< Error > validateKillPolicy(const TaskInfo &task)
Option< Error > validateRoles(const mesos::FrameworkInfo &frameworkInfo)
Definition: agent.hpp:25
Option< Error > validateType(const ExecutorInfo &executor)
process::Future< Nothing > destroy(const std::string &hierarchy, const std::string &cgroup="/")
Option< Error > validateTaskGroupAndExecutorResources(const TaskGroupInfo &taskGroup, const ExecutorInfo &executor)
Option< Error > validateCheck(const TaskInfo &task)
bool detectOverlappingSetAndRangeResources(const std::vector< Resources > &resources)
Definition: grp.hpp:26
Definition: none.hpp:27
Definition: attributes.hpp:24
Option< Error > validateHealthCheck(const TaskInfo &task)
Option< Error > validateOfferFilters(const FrameworkInfo &frameworkInfo)
Definition: master.hpp:122
Option< Error > validateOfferConstraintsRoles(const std::set< std::string > &validFrameworkRoles, const scheduler::OfferConstraints &offerConstraints)
Option< Error > validate(const mesos::master::Call &call)
Option< Error > validateTaskAndExecutorResources(const TaskInfo &task)
Offer * getOffer(Master *master, const OfferID &offerId)
Option< Error > validateSingleResourceProvider(const google::protobuf::RepeatedPtrField< Resource > &resources)
Try< Nothing > create(const std::string &hierarchy, const std::string &cgroup, bool recursive=false)
void preserveImmutableFields(const FrameworkInfo &oldInfo, FrameworkInfo *newInfo)
Definition: master.hpp:2397
Definition: master.hpp:355
Option< Error > registerSlave(const RegisterSlaveMessage &message)