Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions RFCs/2021-04-16-76-collection-policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Collection policies direct pktvisor to use Taps (#75) to create an instance of a
and attach handlers to it. Processing takes place, and the data is exposed for sinks to collect. These policies may be
given directly to pktvisor via command line or through the Admin API if available.

Policies require a `kind` to indicate the type of policy being applied.

`collection-policy-anycast.yaml`

```yaml
Expand All @@ -15,6 +17,7 @@ visor:
policies:
# policy name and description
anycast_dns:
kind: collection
description: "base anycast DNS policy"
# input stream to create based on the given tap and optional filter config
input:
Expand Down
2 changes: 2 additions & 0 deletions cmd/pktvisord/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,10 @@ version: "1.0"
host_spec: "{}"
policies:
default:
kind: collection
input:
tap: default
input_type: pcap
config:
bpf: "{}"
handlers:
Expand Down
8 changes: 8 additions & 0 deletions src/Policies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ std::vector<Policy *> PolicyManager::load(const YAML::Node &policy_yaml)
throw PolicyException("expecting policy configuration map");
}

// Policy kind defines schema
if (!it->second["kind"] || !it->second["kind"].IsScalar()) {
throw PolicyException("missing or invalid policy kind at key 'kind'");
}
if (it->second["kind"].as<std::string>() != "collection") {
throw PolicyException(fmt::format("unknown policy kind: {}", it->second["kind"].as<std::string>()));
}

// Input Section
if (!it->second["input"] || !it->second["input"].IsMap()) {
throw PolicyException("missing or invalid policy input stream configuration at key 'input'");
Expand Down
30 changes: 30 additions & 0 deletions src/tests/test_policies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ version: "1.0"
policies:
# policy name and description
default_view:
kind: collection
# description: "a mock view of anycast traffic"
# input stream to create based on the given tap and optional filter config
input:
Expand Down Expand Up @@ -71,6 +72,7 @@ version: "1.0"
iface: eth0
policies:
default_view:
kind: collection
input:
tap: nonexist
input_type: mock
Expand All @@ -87,6 +89,7 @@ version: "1.0"
iface: eth0
policies:
default_view:
kind: collection
input:
tap: anycast
input_type: mock
Expand All @@ -106,6 +109,7 @@ version: "1.0"
iface: eth0
policies:
default_view:
kind: collection
input:
tap: anycast
input_type: mock
Expand All @@ -127,10 +131,27 @@ version: "1.0"
iface: eth0
policies:
default_view:
kind: collection
input:
tap: anycast
input_type: wrong_type
)";
auto policies_config_bad6 = R"(
version: "1.0"

visor:
taps:
anycast:
input_type: mock
config:
iface: eth0
policies:
default_view:
kind: unknown_kind
input:
tap: anycast
input_type: mock
)";

TEST_CASE("Policies", "[policies]")
{
Expand Down Expand Up @@ -221,6 +242,15 @@ TEST_CASE("Policies", "[policies]")
REQUIRE_THROWS_WITH(registry.policy_manager()->load(config_file["visor"]["policies"]), "unable to instantiate tap 'anycast': input_type for policy specified tap 'anycast' doesn't match tap's defined input type: wrong_type/mock");
}

SECTION("Bad Config: bad policy kind")
{
CoreRegistry registry(nullptr);
YAML::Node config_file = YAML::Load(policies_config_bad6);

REQUIRE_NOTHROW(registry.tap_manager()->load(config_file["visor"]["taps"], true));
REQUIRE_THROWS_WITH(registry.policy_manager()->load(config_file["visor"]["policies"]), "unknown policy kind: unknown_kind");
}

SECTION("Roll Back")
{
CoreRegistry registry(nullptr);
Expand Down