| 1830 | |
| 1831 | |
| 1832 | Future<Response> Master::Http::reserve( |
| 1833 | const Request& request, |
| 1834 | const Option<Principal>& principal) const |
| 1835 | { |
| 1836 | // TODO(greggomann): Remove this check once the `Principal` type is used in |
| 1837 | // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map. |
| 1838 | // See MESOS-7202. |
| 1839 | if (principal.isSome() && principal->value.isNone()) { |
| 1840 | return Forbidden( |
| 1841 | "The request's authenticated principal contains claims, but no value " |
| 1842 | "string. The master currently requires that principals have a value"); |
| 1843 | } |
| 1844 | |
| 1845 | // When current master is not the leader, redirect to the leading master. |
| 1846 | if (!master->elected()) { |
| 1847 | return redirect(request); |
| 1848 | } |
| 1849 | |
| 1850 | if (request.method != "POST") { |
| 1851 | return MethodNotAllowed({"POST"}, request.method); |
| 1852 | } |
| 1853 | |
| 1854 | // Parse the query string in the request body. |
| 1855 | Try<hashmap<string, string>> decode = |
| 1856 | process::http::query::decode(request.body); |
| 1857 | |
| 1858 | if (decode.isError()) { |
| 1859 | return BadRequest("Unable to decode query string: " + decode.error()); |
| 1860 | } |
| 1861 | |
| 1862 | // Helper function to parse a list of resource from query parameters. |
| 1863 | auto parseResourcesList = []( |
| 1864 | const std::string& key, |
| 1865 | const hashmap<string, string>& queryParameters) |
| 1866 | -> Try<RepeatedPtrField<Resource>> |
| 1867 | { |
| 1868 | Option<string> value = queryParameters.get(key); |
| 1869 | if (value.isNone()) { |
| 1870 | return Error( |
| 1871 | "Missing '" + key + "' query parameter in the request body"); |
| 1872 | } |
| 1873 | |
| 1874 | Try<JSON::Array> parse = |
| 1875 | JSON::parse<JSON::Array>(value.get()); |
| 1876 | |
| 1877 | if (parse.isError()) { |
| 1878 | return Error( |
| 1879 | "Error parsing '" + key + |
| 1880 | "' query parameter in the request body: " + parse.error()); |
| 1881 | } |
| 1882 | |
| 1883 | RepeatedPtrField<Resource> resources; |
| 1884 | foreach (const JSON::Value& value, parse->values) { |
| 1885 | Try<Resource> resource = ::protobuf::parse<Resource>(value); |
| 1886 | if (resource.isError()) { |
| 1887 | return Error( |
| 1888 | "Error parsing '" + key + |
| 1889 | "' query parameter in the request body: " + resource.error()); |