istio-ecosystem / wasm-extensions

Contains miscellaneous Wasm extensions for Istio
Apache License 2.0
108 stars 35 forks source link

Is there a problem with the attributegen match logic? #89

Open mark8s opened 1 year ago

mark8s commented 1 year ago

When I use the following code, I found that as long as the first condition does not match successfully, then my second match will never go. Is this a bug in the code? ? ?

patch:
      operation: INSERT_BEFORE
      value:
        name: istio.attributegen
        typed_config:
          "@type": type.googleapis.com/udpa.type.v1.TypedStruct
          type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
          value:
            config:
              configuration:
                "@type": type.googleapis.com/google.protobuf.StringValue
                value: |
                  {
                    "attributes": [
                      {
                        "output_attribute": "x_route",
                        "match": [
                          {
                            "value": "x-gray",
                            "condition": "request.headers['end-user'] == 'mark'"
                          },
                          {
                            "value": "x-normal"
                          }
                        ]
                      }
                    ]
                  }
              vm_config:
                runtime: envoy.wasm.runtime.null
                code:
                  local: { inline_string: "envoy.wasm.attributegen" }

source code:

// class Match
// Returns the result of evaluation or nothing in case of an error.
std::optional<bool> Match::evaluate() const {
  if (condition_.empty()) {
    return true;
  }

  std::optional<bool> ret = {};

  const std::string function = "expr_evaluate";
  char* out = nullptr;
  size_t out_size = 0;
  auto result = proxy_call_foreign_function(function.data(), function.size(),
                                            reinterpret_cast<const char*>(&condition_token_),
                                            sizeof(uint32_t), &out, &out_size);

  if (result != WasmResult::Ok) {
    LOG_TRACE(absl::StrCat("Failed to evaluate expression:[", condition_token_, "] ", condition_,
                           " result: ", toString(result)));
  } else if (out_size != sizeof(bool)) {
    LOG_TRACE(absl::StrCat("Expression:[", condition_token_, "] ", condition_,
                           " did not return a bool, size:", out_size));
  } else {
    // we have a bool.
    bool matched = *reinterpret_cast<bool*>(out);
    ret = std::optional<bool>{matched};
  }

  if (out != nullptr) {
    free(out);
  }

  return ret;
}

istio-proxy log:

image