Burgyn/MMLib.SwaggerForOcelot

Getting 404 when running with KubernetesServiceDiscoveryProvider

Prod0 opened this issue · 8 comments

Prod0 commented

Same problem as this post: #251

Describe the bug
When running a local ocelot.json it's working perfectly.
With these settings:

{
    "Routes": [
        {
            "SwaggerKey": "multitenant",
            "DownstreamPathTemplate": "/api/{everything}",
            "DownstreamScheme": "https",
            "DownstreamHostAndPorts": [
                {
                    "Host": "localhost",
                    "Port": 5001
                }
            ],
            "UpstreamPathTemplate": "/multitenant/{everything}",
            "UpstreamHttpMethod": [  ],
            "RouteIsCaseSensitive": false,
            "AuthenticationOptions": {
                "AuthenticationProviderKey": "Admin",
                "AllowedScopes": []
            }
        }
    ],
    "GlobalConfiguration": {
        "BaseUrl": "https://localhost:5021",
         "ServiceDiscoveryProvider": { }
    },
    "SwaggerEndPoints":
    [
      {
        "Key": "multitenant",
        "Config": [
          {
            "Name": "Multitenant API",
            "Version": "v1", 
            "Url": "https://localhost:5001/api/swagger/docs/v1/swagger.json"
          }
        ]
      }
    ]
}

But when using these settings on kubernetes:

{
    "Routes": [
        {
            "SwaggerKey": "multitenant",
            "DownstreamPathTemplate": "/api/{everything}",
            "DownstreamScheme": "http", 
            "DownstreamHostAndPorts": [
                {
                    "Host": "URLKUBERNETES",
                    "Port": 80
                }
            ],
            "UpstreamPathTemplate": "/multitenant/{everything}",
            "UpstreamHttpMethod": [ "Options", "Head","Get", "Post" , "Put", "Patch", "Delete"],
            "RouteIsCaseSensitive": false,
            "DangerousAcceptAnyServerCertificateValidator": true,
            "AuthenticationOptions": {
                "AuthenticationProviderKey": "Admin",
                "AllowedScopes": []
            },
            "VirtualDirectory":"/api"
        }
    ],
    "GlobalConfiguration": {
        "BaseUrl": "BASEURL",
        "ServiceDiscoveryProvider": {
          "Namespace": "NAMESPACE",
          "Type": "kube"   
        }
    },
    "SwaggerEndPoints":
    [
      {
          "Key": "multitenant", 
          "Config": [
            {
              "Name": "Multitenant API",
              "Version": "v1",
              "Service": {
                "Name": "multitenant",
                "Path": "/swagger/docs/v1/swagger.json"
              }
            }
          ]
      }
    ]
}

I'm getting 404 for /swagger/index.html with a :
Fetch error
Not Found /api/swagger/docs/v1/multitenant

but when I actually route to /swagger/docs/v1/multitenant in Postman
I get the swagger.json file perfectly.

The routing works on kuberentes, also seems like getting the swagger.json file from downstream service.
For some reason the /swagger endpoint is still showing 404.

Expected behavior
Same as with the first settings file, swagger should work.

I would really appreciate some help, thanks!

Hi @Prod0,

If you use it in Postman, your path is /swagger/docs/v1/multitenant (without /api). But in the Not Found message it is /api/swagger/docs/v1/multitenant (with /api).

Try to remove the "VirtualDirectory":"/api" parameter from the route definition.

Prod0 commented

I tried to remove this parameter, and I receive this error after in my Kibana log

Error Code: UnableToFindDownstreamRouteError Message: Failed to match Route configuration for upstream path: /swagger/docs/v1/multitenant, verb: GET. errors found in ResponderMiddleware. Setting error response for request path:/swagger/docs/v1/multitenant, request method: GET"

Also I forgot to mention that the multitenant service required authentication, it's not public opened, so even if config is correct I will get error 401, and gateway swagger doesn't have any possibility to authenticate and after to send the token to down stream API.

Also here there is the configuration of multitenant API

        app.UseSwagger(c =>
        {
            c.RouteTemplate = "api/swagger/docs/{documentName}/swagger.json";
        });
        app.UseSwaggerUI(options =>
        {
            options.RoutePrefix = "api/swagger";
            options.SwaggerEndpoint("/api/swagger/docs/v1/swagger.json", "Multitenant API");
        });

How is it possible that when you call it from Postman without /api you get the correct data even if you have api/swagger/docs/{documentName}/swagger.json configured in the downstream service?


Authorization. SwaggerUI calls Ocelot first, where the middleware calls the downstream service. So the call to the downstream service does not happen directly. If you need to add some headers for authorization, you can use

app.UseSwaggerForOcelotUI(opt => {
  opt.DownstreamSwaggerHeaders = new[]
  {
      new KeyValuePair<string, string>("Auth-Key", "AuthValue"),
  };
})
Prod0 commented

Ok my bad I was using this URL : api/multitenant/swagger/index.html ... in the postman, sorry for that.

the thing is that we dont call locally domain/api/swagger/docs/{documentName}/swagger.json
but domain/api/multitenant/swagger/docs/v1/swagger.json

But regarding to the DownstreamHeaders,
The error is that we cant find the upstream route
if we can get from multitenant any error code that we could set some headers but we didnt reach this step
we only asking gateway and it reply sorry url is not matching configuration
also we run swagger : https://domain/swagger/index.html without api prefix where multitenant require api prefix

Prod0 commented

@Burgyn please

Hi, I'm sorry but I can't help you much. Can you please isolate this behavior into a demo example and provide it to me?

Closing after 8 days of waiting for the additional info requested.

Prod0 commented

Hello @Burgyn, where can I send you the demo project, sorry for the delay.