Skip to content
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

Typing #41

Closed
wants to merge 7 commits into from
Closed

Typing #41

wants to merge 7 commits into from

Conversation

alexsnaps
Copy link
Member

@alexsnaps alexsnaps commented Aug 25, 2023

Still work in progress, if only because of two things:

  • Just as on main this returns an empty string on misses
  • The as_literal syntax will need to be supported on the limitador end too
  • Still working on adding support for the more complex types which are afaict protobuff encoded

@alexsnaps alexsnaps requested a review from eguzki August 25, 2023 15:47
src/filter/http_context.rs Outdated Show resolved Hide resolved
src/filter/http_context.rs Outdated Show resolved Hide resolved
src/filter/http_context.rs Outdated Show resolved Hide resolved
}
Some(attribute_bytes) => match self.property_mapper.typed(path, attribute_bytes) {
Ok(tp) => tp,
Err(raw) => TypedProperty::string(raw),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if we fail to map a known property, we try to make it a String which in turn may fail, when there is an invalid byte sequence, which then becomes a Bytes. I added support for that in the as_literal tho unsure what one would do this that...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then maybe return Result<Option<TypedProperty>, Vec<u8>> instead of option and leave the decision to the caller?

In any case, what I would do is logging error saying.. "property A could not be parsed".

When the caller is the pattern expression, the error could be "overlooked" as "", while the descriptor builder can fallback to default field value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the current approach which clearly separate the two concerns...
Now I could not fold the error case in the TypedProperty::string function, but I am of the opinion that's the behavior we should aim for: unknown is tried as a String, if it isn't proper UTF-8, we fall back to string encoded bytes (see TypedProperty::as_string or ::as_literal for TypedProperty::Bytes)

Comment on lines +162 to +177
properties.insert(
"auth.metadata".to_string(),
Box::new(TypedProperty::complex_map),
);
properties.insert(
"auth.authorization".to_string(),
Box::new(TypedProperty::complex_map),
);
properties.insert(
"auth.response".to_string(),
Box::new(TypedProperty::complex_map),
);
properties.insert(
"auth.callbacks".to_string(),
Box::new(TypedProperty::complex_map),
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth.* are not properties that can be requested directly to the host through the ABI, right? For that reason they were unchecked for "RL" in RFC 0002 for now. Seeing them here makes me think we may want to progress to the point where these attributes are abstractions that translate to metadata.filter_metadata.envoy\.filters\.http\.ext_authz.* perhaps?

Do we need a special TypedProperty function to handle them maybe?

Another option would be the "translation" to happen in the policy controller, and therefore the wasm shim won't ever even need to know about them.

Copy link
Member Author

@alexsnaps alexsnaps Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually merely defines the typing... but you are right that I conflated the typing with the host. Filter::get_typed_property is actually what decides where the property is to be sourced.

Maybe I should treat all auth related ones differently... tho they'd still use some typed mapper function just as the envoy properties do... 🤔

"request.raw_body".to_string(),
Box::new(TypedProperty::bytes),
);
properties.insert("auth.identity".to_string(), Box::new(TypedProperty::bytes));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@eguzki eguzki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that at the http_context.rs level:

  • pattern expressions are evaluated with gateway specific implementation returning true or false. It would also require a gateway specific implementation for the parsing of the value field (that could also defined as byte array to be whatever, ie. json int, string, array or object).
  • on descriptor building, data selectors call gateway specific implementation returning Option<String> (as RLS only accepts strings). (Or maybe Result<Option<String>, <Vec<u8>> for dealing with parsing errors)

Needless to say the only gateway implementation for now is envoy.

Does it makes sense what I say ❓

@@ -30,6 +30,8 @@ mod timestamp;
mod token_bucket;
mod value;

pub mod properties;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code from src/envoy has been copied&pasted from somewhere else. What if we "upgrade" this dependency?

}
}

pub fn timestamp(bytes: Vec<u8>) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is WIP. I would expect this parsing to be according to ProtocolBuffers Timestamp struct. Right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, isn't this Envoy Specific implementation? Do we want to encapsulate envoy specific things?

}
}

impl PartialEq<str> for TypedProperty {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why comparing as strings for all cases? Planning to strings types compare with strings, integer types compare with integers, and so on...?

src/filter/http_context.rs Outdated Show resolved Hide resolved
src/filter/http_context.rs Outdated Show resolved Hide resolved
src/filter/http_context.rs Outdated Show resolved Hide resolved
}
Some(attribute_bytes) => match self.property_mapper.typed(path, attribute_bytes) {
Ok(tp) => tp,
Err(raw) => TypedProperty::string(raw),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then maybe return Result<Option<TypedProperty>, Vec<u8>> instead of option and leave the decision to the caller?

In any case, what I would do is logging error saying.. "property A could not be parsed".

When the caller is the pattern expression, the error could be "overlooked" as "", while the descriptor builder can fallback to default field value.

},
let typed_property = match self.get_typed_property(&selector_item.selector) {
Some(typed_property) => typed_property,
None => return None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is &selector_item.default being used when the typed property is not found?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not there right now, as it itself introduces a rather non neglectable refactoring of this PR: tl;dr it needs type inference and coercing from the now not String value, but a Value literal.

@alexsnaps
Copy link
Member Author

Superseded by #60

@alexsnaps alexsnaps closed this Jul 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request target/next
Projects
Status: Done
Status: In Progress
Development

Successfully merging this pull request may close these issues.

3 participants