Swagger plus Ocelot - swagger

I´m trying to implement a gateway with ocelot and swagger (https://github.com/Burgyn/MMLib.SwaggerForOcelot). I was able to configure everything well in my localhost, now I need to deploy my solution to kubernetes, but, because there are some features been developed in paralell, I was requested to deploy my solution in a subdirectory, something like this.
https://domain/Feature1/gateway1
https://domain/Feature2/gateway2
...
They don´t what to have a subdomain by feature.
My configuration works but there is a problem with swagger UI, because the test paths are maped like this.
https://domain/api/service/method
but I need something like
https://domain/Feature1/api/service/method
Is it posible?

I'm not really sure if I help, but MMLib.SwaggerForOcelot support Virtual Directory. Please try this

Maybe it could help to someone, this is the only way i could make this setup to work.
Reach the swagger docs in:
https://domain/gatewayfeature1
And the apis in:
https://domain/apisfeature1
The same for another feature.
Docs
https://domain/gatewayfeature2
Apis
https://domain/apisfeature2
I'm using nginx as reverse proxy and ocelot as gateway for my apis in and GKE cluster.
The ingress yaml that I ended using is this by feature, "apifeature1", "apifeature2",...
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: "true"
name: test
namespace: default
spec:
rules:
- host: testdomain
http:
paths:
- backend:
serviceName: gateway-feature1
servicePort: 80
path: /docsfeature1/(.*)
- backend:
serviceName: gateway-feature1
servicePort: 80
path: /(apifeature1/.*)
The Ocelot Config by feature "apifeature1", "apifeature2",...
In this case I´m reading the feature name from the configuration, so the ocelot config ends like this example.
{
"UpstreamPathTemplate": "/apifeature1/api/controller/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "apifeature1",
"Port": "80"
}
],
"SwaggerKey": "api"
},
And the gateway by feature.
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/apifeature1");
return next();
});
.
.
.
app.UseSwaggerForOcelotUI(c =>
{
c.DownstreamSwaggerEndPointBasePath = "/apifeature1/swagger/docs";
c.PathToSwaggerGenerator = "/apifeature1/swagger/docs";
c.DocumentTitle = "DOCUMENT";
});
It works, but, I think it could be improved.

Related

nginx-ingress shows HTTP Error 404 for a react app deployed on Domain path, but works for subdomain path

Here is my ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: 8link-app-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: link8.in
http:
paths:
- backend:
service:
name: link8-app-prod-svc
port:
number: 80
path: /
pathType: Prefix
- host: test.link8.in
http:
paths:
- backend:
service:
name: link8-app-prod-svc
port:
number: 80
path: /
pathType: Prefix
In the above ingress, I have the same Front-end service which is defined to be run on both Domain and sub-domain (for the testing), it is working for sub-domain but not for the domain.
I get Error 404 on domain path:
Following is my DNS settings, where value is my Ingress Address:
UPDATE:
In order to clear things for anyone, who will try to figure out the answer.
The question was answered by the author.
The problem was not in Kubernetes resources of any kind, it was a browser-specific issue, clearing the browser storage solved the problem.
my problem wasn't related to k8s;
it was working from start.
Just I had to clear everything for my domain in chrome storage

Kubernetes - Ingress on docker driver - minikube 1.16

I'm trying to setup ingress on docker driver for minikube 1.16 on windows 10 home (build 19042).
Ingress on docker driver wasn't supported before but it is now on minikube 1.16:
https://github.com/kubernetes/minikube/pull/9761
I've been trying something by myself but i got ERR_CONNECTION_REFUSED when connecting to the ingress at 127.0.0.1 OR kubernetes.docker.internal
Steps:
minikube start
minikube addons enable ingress
create deployment
create ClusterIP
Ingress config
Here is my configuration:
#cluster ip service
apiVersion: v1
kind: Service
metadata:
name: client-cluster-ip-service
spec:
type: ClusterIP
selector:
component: web
ports:
- port: 3000
targetPort: 3000
# not posting deployment code because it's not relevant, but there is a deployment with selector 'component:web' and it's exposing port 3000.
#ingress service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: kubernetes.docker.internal
http:
paths:
- path: /?(.*)
pathType: Prefix
backend:
service:
name: client-cluster-ip-service
port:
number: 3000
I have dns redirect in hosts file.
I've also tried "minikube tunnel" on another terminal but no luck either.
Thanks!
There is a mistake in your ingress object definition under rules field:
rules:
- host: kubernetes.docker.internal
- http:
paths:
The exact problem is the - sing in front the http which makes the host and http separate arrays.
Take a look how your converter yaml looks like in json:
{
"spec": {
"rules": [
{
"host": "kubernetes.docker.internal"
},
{
"http": {
"paths": [
{
"path": "/?(.*)",
"pathType": "Prefix",
"backend": {
---
This is how annotations looks like with your ingress definition.
spec:
rules:
- host: kubernetes.docker.internal
http:
paths:
- path: /?(.*)
pathType: Prefix
And now notice how this yaml converted to json looks like:
{
"spec": {
"rules": [
{
"host": "kubernetes.docker.internal",
"http": {
"paths": [
{
"path": "/?(.*)",
"pathType": "Prefix",
"backend": {
---
You can easily visualize this even better using yaml-viewer

Nginx Ingress Controller Returns 404 Kubernetes

I am trying to create an ingress controller that points to a service that I have exposed via NodePort.
Here is the yaml file for the ingress controller (taken from https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/):
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: hello-world.info
http:
paths:
- path: /
backend:
serviceName: appName
servicePort: 80
I can connect directly to the node port and the frontend is displayed.
Please note that I am doing this because the frontend app is unable to connect to other deployments that I have created and I read that an ingress controller would be able to solve the issue. Will I still have to add an Nginx reverse proxy? If so how would I do that? I have tried adding this to the nginx config file but with no success.
location /middleware/ {
proxy_pass http://middleware/;
}
You must use a proper hostname to reach the route defined in the Ingress object. Either update your /etc/hosts file or use curl -H "hello-world.info" localhost type command. Alternatively, you can delete the host mapping and redirect all traffic to one default service.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: appName
servicePort: 80

Swagger UI try it out internally in kubernetes

i have deployed swagger UI on Kubernetes. now it's not sending a request to internal service of Kubernetes when clicking on the Try it out button.
Since all service running locally in Kubernetes we have to use HTTP but my swagger UI is on HTTPS so getting mixed content error also.
is there any way we can invoke internal service using swagger UI running inside Kubernetes.
this is my demo swagger.yaml :
openapi: 3.0.1
servers:
- url: '{scheme}://test-service'
variables:
scheme:
description: 'The Data Set API is accessible via https and http'
enum:
- 'https'
- 'http'
default: 'https'
info:
description: >-
i would rather suggest using ingress and add further rule with https domain.
ingress :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: swagger-staging
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: swagger-ingress
namespace: default
spec:
rules:
- host: example.com
http:
paths:
- path: /test-service(/|$)(.*)
backend:
serviceName: service-1
servicePort: 80
- path: service-2(/|$)(.*)
backend:
serviceName: service-2
servicePort: 80
- path: /service-3(/|$)(.*)
backend:
serviceName: service-3
servicePort: 80
- path: /service-4(/|$)(.*)
backend:
serviceName: service-4
servicePort: 80
- path: /service-5(/|$)(.*)
backend:
serviceName: service-5
servicePort: 80
note : if you will try updating ingress with https and later try with port-forward it will not work and same give error of browser mixed content .
You can use port-forwarding:
kubectl -n <namespace> port-forward svc/<your-swagger-service> <localhost-port>:<swagger-port-in-your-svc>
And then go to localhost:<localhost-port>
Another way to that is using internal load balancer there's some options depends on your cloud provider.

How to get oauth2_proxy running in kubernetes under one domain to redirect back to original domain that required authentication?

I've been setting up a kubernetes cluster and want to protect the dashboard (running at kube.example.com) behind the bitly/oauth2_proxy (running at example.com/oauth2 on image a5huynh/oauth2_proxy:latest) as I want to re-use the OAuth proxy for other services I will be running. Authentication is working perfectly but after a user logs in, i.e. the callback returns, they are sent to example.com where instead they should be sent to the original host kube.example.com that initiated the flow. How can I do this? (I am using the nginx-ingress-controller).
Annotation on OAuth2 Proxy:
kubernetes.io/ingress.class: "nginx",
nginx.ingress.kubernetes.io/force-ssl-redirect: "true",
nginx.ingress.kubernetes.io/secure-backends: "true",
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
Annotation on Dashboard:
kubernetes.io/ingress.class: "nginx",
nginx.ingress.kubernetes.io/auth-signin: "https://example.com/oauth2/start",
nginx.ingress.kubernetes.io/auth-url: "https://example.com/oauth2/auth",
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS",
nginx.ingress.kubernetes.io/force-ssl-redirect: "true",
nginx.ingress.kubernetes.io/secure-backends: "true",
nginx.ingress.kubernetes.io/ssl-passthrough: "true",
nginx.ingress.kubernetes.io/ssl-redirect: "true"
I expect to be redirected to the original host kube.example.com after OAuth flow is complete but am being sent back to the OAuth2 host example.com
After searching for a bit I came across a blog post about performing this in a super simple manor. Unfortunately I found the provided yaml did not quite work correctly as the oauth2_proxy was never being hit due to nginx intercepting all requests (I am not sure if mine was not working due to me wanting the oauth-proxy url to be example.com/oauth2 rather than oauth2.example.com). To fix this I added back the oauth2-proxy path to the Ingress for the proxy i.e.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: 80
path: /
- backend:
serviceName: oauth2-proxy
servicePort: 4180
path: /oauth2
and made sure that the service was also still exposed i.e.
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: oauth2-proxy
name: oauth2-proxy
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
- name: http-proxy
port: 4180
protocol: TCP
targetPort: 4180
selector:
k8s-app: oauth2-proxy
Then to protect services behind the oauth proxy I just need to place the following in the Ingress annotations:
nginx.ingress.kubernetes.io/auth-url: "https://example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://example.com/oauth2/start?rd=/redirect/$http_host$request_uri"

Resources