-
Notifications
You must be signed in to change notification settings - Fork 665
Change pathz telemetry to be per policy rather than per path #1282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
No major YANG version changes in commit 85df6a2 |
68d114a
to
696db95
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module: openconfig-gnsi-pathz
augment /oc-sys:system:
+--ro gnmi-pathz-policies
+--ro policies
+--ro policy* [instance]
+--ro instance -> ../state/instance
+--ro state
+--ro instance? enumeration
+--ro version? version
+--ro created-on? created-on
augment /oc-sys:system/oc-sys-grpc:grpc-servers/oc-sys-grpc:grpc-server/oc-sys-grpc:state:
+--ro gnmi-pathz-policy-version? version
+--ro gnmi-pathz-policy-created-on? created-on
augment /oc-sys:system/oc-sys-grpc:grpc-servers/oc-sys-grpc:grpc-server:
+--ro gnmi-pathz-policy-counters
+--ro paths
+--ro path* [name]
+--ro name -> ../state/name
+--ro state
+--ro name? string
+--ro reads
| +--ro access-rejects? oc-yang:counter64
| +--ro last-access-reject? oc-types:timeticks64
| +--ro access-accepts? oc-yang:counter64
| +--ro last-access-accept? oc-types:timeticks64
+--ro writes
+--ro access-rejects? oc-yang:counter64
+--ro last-access-reject? oc-types:timeticks64
+--ro access-accepts? oc-yang:counter64
+--ro last-access-accept? oc-types:timeticks64
LGTM, couple of editorial suggestions.
Co-authored-by: Rob Shakir <[email protected]>
For reference, the updated proposed tree:
Some comments to consider:
|
gnsi pathz only applies to gnmi... what other server do you think it would relate to? |
So the above should only be visible under a But I was moreso getting at the version and created-on are applied globally to the element and not per grpc-server instance. If one wanted to say create 2 listening grpc-servers, 1 in global RIB, 1 in management they would share the same global policy thus shouldnt the applied policy be outside these servers and more well suited under something like
ok, if we scratch the users out of this, should we not pair up the nomenclature to the proto (e.g. |
+1 to the
Each node can have multiple gnmi-servers (for instance, when an operator has multiple mgmt vrfs, inband, oob, etc). This is quite common. |
} | ||
container reads { | ||
description | ||
"The counter were collected while | ||
performing a read operation on the | ||
schema path."; | ||
performing read operations on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what, exactly, is a read operation
on the policy?
Is it a single RPC allowed/denied by the policy (regardless of a number of paths authorized, e.g. a GetRequest with 10 allowed paths will be counted as +1?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested description:
"The number of gnmi.Get and gnmi.Subscribe RPC's that match the policy and were accepted or rejected. "
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By "accept/rejected" do you mean "permitted/denied by the policy"?
its not really that binary - a gNMI read operation can be a mix of permitted and denied paths.
For example, if the policy is "permit read /a
and deny read /a/b
", and /a/b
exists in YANG, then a request to read /a
will be partially permitted, partially denied.
uses counters; | ||
} | ||
container writes { | ||
description | ||
"The counter were collected while | ||
performing a write operation on the | ||
schema path."; | ||
performing write operations on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question as for the reads, please specify the exact definition of what should be counted here (number of set requests, number of individual operations in each request, etc)
+1 to the per policy per server vs per policy question. I think the current model assumes that an instance of the service (e.g. pathz) is per grpc-server. In some cases this may make sense, but in others it does not. For example: pathz is supposed to rotate the policy for the node and not for the server it is tied to, regardless of how many grpc-server instances are configured (note that one may still configure gNMI across multiple servers for different reasons - the model allows it). |
@@ -109,62 +115,44 @@ module openconfig-gnsi-pathz { | |||
description | |||
"A collection of counters collected by the gNSI.pathz module."; | |||
|
|||
container gnmi-pathz-policy-counters { | |||
container policies { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be called 'pathz' so that the yang tree looks as follows:
/system/grpc-servers/grpc-server
+--ro pathz
+--ro policy* [name]
+--ro name -> ../state/name
+--ro state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Building on these suggestions:
Lists need to follow OC style guide, (lists/list) and strongly recommend using a counters container for those leaves, following precedent in most of the rest of the OC models.
augment /oc-sys:system/oc-sys-grpc:grpc-servers/oc-sys-grpc:grpc-server:
+--ro pathz
+--ro policies
+--ro policy* [name]
+--ro name -> ../state/name
+--ro state
+--ro name? string
+--ro last-read-reject? oc-types:timeticks64
+--ro last-read-accept? oc-types:timeticks64
+--ro last-write-reject? oc-types:timeticks64
+--ro last-write-accept? oc-types:timeticks64
+--ro counters
| +--ro read-rejects? oc-yang:counter64
| +--ro read-accepts? oc-yang:counter64
+--ro write-rejects? oc-yang:counter64
+--ro write-accepts? oc-yang:counter64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comments - this should not be "per gRPC server instance" so I believe the anchor point is incorrect first and foremost.
The gNSI suite should be looked at hollisically of which there are some gRPC APIs to interact (there could very well be others both native or in other OC methods)
But wherever the anchor point ends up - +1 to the last comment in order to follow the encapsulation of lists inside containers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, your suggestion could perhaps be stated as reserving the /system/grpc-servers/grpc-server
subtree to paths which are generic across any/all grpc servers (which means it will only have things like a connection list and packet/byte counters).
The anchor for pathz can be at the system level since pathz is a "system-wide" entity.
augment /oc-sys:system/:
+--ro pathz
+--ro policies
+--ro policy* [name]
+--ro name -> ../state/name
+--ro state
+--ro name? string
+--ro last-read-reject? oc-types:timeticks64
+--ro last-read-accept? oc-types:timeticks64
+--ro last-write-reject? oc-types:timeticks64
+--ro last-write-accept? oc-types:timeticks64
+--ro counters
| +--ro read-rejects? oc-yang:counter64
| +--ro read-accepts? oc-yang:counter64
+--ro write-rejects? oc-yang:counter64
+--ro write-accepts? oc-yang:counter64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so I believe the anchor point is incorrect first and foremost.
It is not necessarily incorrect, but there's a mismatch between the PR description and the anchor point.
You can apply the same policy to multiple servers, but still implement per-server counters, especially if (as @dplore suggested) the purpose of this PR is to count number of accepted/denied RPCs (which hasn't been confirmed yet).
After changes in openconfig/gnsi/pull/219, and combined with the idea of doing per-RPC counters, we are essentially in the authz-like territory which already implements per-server counters
https://github.com/openconfig/public/blob/master/release/models/gnsi/openconfig-gnsi-authz.yang
Which kind of brings the question, do we really need all these separate counters? Might as well just do combined per-grpc server statistics for both authz and pathz rejects.
Nice to see the move away from xpaths :) I have a few initial thoughts on this proposal:
|
Considering that the state is ephemeral, that doesn't seem particularly useful either. I'd vote for simplification (count things only for one active policy; TBD with or without per-server granularity) |
Isn't the 'read-rejects' counter a potential security issue? It feels like it could be used as a probe to discover information about the configuration or state that the reader isn't supposed to know. E.g. try reading a particular list to see if any entries are in it (reading some ancestor container), or trying a specific key. |
There is a mention of Subscribe RPC above. But is access control actually applied at subscription time or is it conceptually applied on the notification data stream? For example: if a user has permission to access interface "foo" but not interface "bar", but interface "bar" doesn't exist yet, and the user subscribes to "all interfaces" (which is only foo at the moment), what happens when interface "bar" is later added to the config? So I'm not sure that a counter for 'rejects' should even apply to Subscribe? |
both, depending on the policy and the subscription content. see the recent discussion in openconfig/gnsi#219
after the latest changes, this subscription will be rejected (regardless of the presence of interface "bar"). [assuming you don't have a blanket /interfaces allow in your policy, only /interfaces/interface[name=foo] is allowed] |
Reviewed in May 13, 2025 OC Operators meeting. Moving to "waiting for author status" so @marcushines can respond to the comments above. One question is, is the goal to count accepted/rejected RPC's or paths? (ie: how should an RPC with 10 paths, 9 are accepted and 1 is rejected be counted?) |
[Note: Please fill out the following template for your pull request. lines
tagged with "Note" can be removed from the template.]
[Note: Before this PR can be reviewed please agree to the CLA covering this
repo. Please also review the contribution guide -
https://github.com/openconfig/public/blob/master/doc/contributions-guide.md]
Change Scope
Refactoring the pathz yang telemetry to be based on per policy rather than by path.
This has been requested by multiple vendors as per path is not needed and causes a very large memory and state management issue
this is not backwards compatible but currently these counters should be in production
Platform Implementations