Added helpers for supporting resource provider selectors. This patches validates that a profile's manifest must have a selector and adds a helper function for selecting resource providers.
Review: https://reviews.apache.org/r/65558/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/00b9ea0f Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/00b9ea0f Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/00b9ea0f Branch: refs/heads/master Commit: 00b9ea0f105c69f00c656418a606c9a13ac7581d Parents: 5aabef4 Author: Chun-Hung Hsiao <chhs...@mesosphere.io> Authored: Thu Feb 8 14:41:25 2018 -0800 Committer: Jie Yu <yujie....@gmail.com> Committed: Thu Feb 8 16:24:02 2018 -0800 ---------------------------------------------------------------------- .../storage/disk_profile_utils.cpp | 124 ++++++++++++++++--- .../storage/disk_profile_utils.hpp | 8 ++ 2 files changed, 118 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/00b9ea0f/src/resource_provider/storage/disk_profile_utils.cpp ---------------------------------------------------------------------- diff --git a/src/resource_provider/storage/disk_profile_utils.cpp b/src/resource_provider/storage/disk_profile_utils.cpp index c84b6e1..cc1c629 100644 --- a/src/resource_provider/storage/disk_profile_utils.cpp +++ b/src/resource_provider/storage/disk_profile_utils.cpp @@ -19,7 +19,9 @@ #include <google/protobuf/util/json_util.h> #include <stout/bytes.hpp> +#include <stout/check.hpp> #include <stout/foreach.hpp> +#include <stout/unreachable.hpp> using std::string; @@ -42,43 +44,137 @@ Try<DiskProfileMapping> parseDiskProfileMapping( if (!status.ok()) { return Error( - "Failed to parse DiskProfileMapping message: " - + status.ToString()); + "Failed to parse DiskProfileMapping message: " + + status.ToString()); } Option<Error> validation = validate(output); if (validation.isSome()) { return Error( - "Fetched profile mapping failed validation with: " + validation->message); + "Fetched profile mapping failed validation with: " + + validation->message); } return output; } +bool isSelectedResourceProvider( + const DiskProfileMapping::CSIManifest& profileManifest, + const ResourceProviderInfo& resourceProviderInfo) +{ + switch (profileManifest.selector_case()) { + case DiskProfileMapping::CSIManifest::kResourceProviderSelector: { + CHECK(profileManifest.has_resource_provider_selector()); + + const auto& selector = profileManifest.resource_provider_selector(); + + foreach (const auto& resourceProvider, selector.resource_providers()) { + if (resourceProviderInfo.type() == resourceProvider.type() && + resourceProviderInfo.name() == resourceProvider.name()) { + return true; + } + } + + return false; + } + case DiskProfileMapping::CSIManifest::kCsiPluginTypeSelector: { + CHECK(profileManifest.has_csi_plugin_type_selector()); + + const auto& selector = profileManifest.csi_plugin_type_selector(); + + return resourceProviderInfo.has_storage() && + resourceProviderInfo.storage().plugin().type() == + selector.plugin_type(); + } + case DiskProfileMapping::CSIManifest::SELECTOR_NOT_SET: { + UNREACHABLE(); + } + } +} + + +static Option<Error> validateSelector( + const DiskProfileMapping::CSIManifest& profileManifest) +{ + switch (profileManifest.selector_case()) { + case DiskProfileMapping::CSIManifest::kResourceProviderSelector: { + if (!profileManifest.has_resource_provider_selector()) { + return Error("Expecting 'resource_provider_selector' to be present"); + } + + const auto& selector = profileManifest.resource_provider_selector(); + + if (selector.resource_providers_size() == 0) { + return Error( + "Expecting one or more 'resource_providers' for " + "ResourceProviderSelector"); + } + + foreach (const auto& resourceProvider, selector.resource_providers()) { + if (resourceProvider.type().empty()) { + return Error( + "'type' is a required field for ResourceProviderSelector"); + } + + if (resourceProvider.name().empty()) { + return Error( + "'name' is a required field for ResourceProviderSelector"); + } + } + + break; + } + case DiskProfileMapping::CSIManifest::kCsiPluginTypeSelector: { + if (!profileManifest.has_csi_plugin_type_selector()) { + return Error("Expecting 'csi_plugin_type_selector' to be present"); + } + + const auto& selector = profileManifest.csi_plugin_type_selector(); + + if (selector.plugin_type().empty()) { + return Error( + "'plugin_type' is a required field for CSIPluginTypeSelector"); + } + + break; + } + case DiskProfileMapping::CSIManifest::SELECTOR_NOT_SET: { + return Error("Expecting a selector to be present"); + } + } + + return None(); +} + + Option<Error> validate(const DiskProfileMapping& mapping) { - auto iterator = mapping.profile_matrix().begin(); - while (iterator != mapping.profile_matrix().end()) { - if (!iterator->second.has_volume_capabilities()) { + foreach (const auto& entry, mapping.profile_matrix()) { + Option<Error> selector = validateSelector(entry.second); + + if (selector.isSome()) { return Error( - "Profile '" + iterator->first + "' is missing the required field " - + "'volume_capabilities"); + "Profile '" + entry.first + "' has no valid selector: " + + selector->message); } - Option<Error> capabilities = - validate(iterator->second.volume_capabilities()); + if (!entry.second.has_volume_capabilities()) { + return Error( + "Profile '" + entry.first + + "' is missing the required field 'volume_capabilities'"); + } + + Option<Error> capabilities = validate(entry.second.volume_capabilities()); if (capabilities.isSome()) { return Error( - "Profile '" + iterator->first + "' VolumeCapabilities are invalid: " - + capabilities->message); + "Profile '" + entry.first + "' has an invalid VolumeCapability: " + + capabilities->message); } // NOTE: The `create_parameters` field is optional and needs no further // validation after parsing. - - iterator++; } return None(); http://git-wip-us.apache.org/repos/asf/mesos/blob/00b9ea0f/src/resource_provider/storage/disk_profile_utils.hpp ---------------------------------------------------------------------- diff --git a/src/resource_provider/storage/disk_profile_utils.hpp b/src/resource_provider/storage/disk_profile_utils.hpp index fa2c7ec..c267da2 100644 --- a/src/resource_provider/storage/disk_profile_utils.hpp +++ b/src/resource_provider/storage/disk_profile_utils.hpp @@ -17,6 +17,8 @@ #ifndef __RESOURCE_PROVIDER_URI_DISK_PROFILE_UTILS_HPP__ #define __RESOURCE_PROVIDER_URI_DISK_PROFILE_UTILS_HPP__ +#include <mesos/mesos.hpp> + #include <stout/option.hpp> #include <stout/try.hpp> @@ -32,6 +34,12 @@ Try<resource_provider::DiskProfileMapping> parseDiskProfileMapping( const std::string& data); +// Helper for checking if a resource provider is selected for a profile. +bool isSelectedResourceProvider( + const resource_provider::DiskProfileMapping::CSIManifest& profileManifest, + const ResourceProviderInfo& resourceProviderInfo); + + // Checks the fields inside a `DiskProfileMapping` according to the // comments above the protobuf. Option<Error> validate(const resource_provider::DiskProfileMapping& mapping);