Skip to content
This repository has been archived by the owner on Jan 20, 2021. It is now read-only.

Add multiple management server support #898

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

utchoang
Copy link

Fixes #895

@utchoang
Copy link
Author

@blueorangutan package

@blueorangutan
Copy link

@utchoang a Jenkins job has been kicked to build primate packages. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result: ✔️centos ✔️debian ✔️archive.
QA: http://primate-qa.cloudstack.cloud:8080/client/pr/898 (JID-3746)

"apiBase": "/client/api",
"servers": [
{
"name": "Manager 1",
Copy link
Member

Choose a reason for hiding this comment

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

This may not always work; due to CORS if they are on different domain and using https.

Copy link
Author

Choose a reason for hiding this comment

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

@rhtyd Will it work well if I use the baseUrl (domain, https) instead of the current one?

Copy link
Author

Choose a reason for hiding this comment

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

@rhtyd what do you think about my way?

@utchoang
Copy link
Author

@blueorangutan package

@blueorangutan
Copy link

@utchoang a Jenkins job has been kicked to build primate packages. I'll keep you posted as I make progress.

@rohityadavcloud rohityadavcloud marked this pull request as ready for review December 22, 2020 06:21
@rohityadavcloud rohityadavcloud marked this pull request as draft December 22, 2020 06:21
@blueorangutan
Copy link

Packaging result: ✔️centos ✔️debian ✔️archive.
QA: http://primate-qa.cloudstack.cloud:8080/client/pr/898 (JID-3764)

@utchoang utchoang marked this pull request as ready for review December 22, 2020 06:31
@utchoang
Copy link
Author

@blueorangutan package

@blueorangutan
Copy link

@utchoang a Jenkins job has been kicked to build primate packages. I'll keep you posted as I make progress.

@blueorangutan
Copy link

Packaging result: ✔️centos ✔️debian ✔️archive.
QA: http://primate-qa.cloudstack.cloud:8080/client/pr/898 (JID-3766)

public/config.json Outdated Show resolved Hide resolved
@ravening
Copy link
Member

@utchoang can you add screenshots if possible?

@utchoang
Copy link
Author

@ravening
image
image

@rohityadavcloud
Copy link
Member

I don't think it'll work due to CORS issues esp if website is served under https.
What do you think @wido @GabrielBrascher @weizhouapache @utchoang @svenvogel @ravening @davidjumani ?

@ravening
Copy link
Member

I don't think it'll work due to CORS issues esp if website is served under https.

What do you think @wido @GabrielBrascher @weizhouapache @utchoang @svenvogel @ravening @davidjumani ?

Will test it and let you know

@wido
Copy link
Contributor

wido commented Jan 12, 2021

I don't think it'll work due to CORS issues esp if website is served under https.
What do you think @wido @GabrielBrascher @weizhouapache @utchoang @svenvogel @ravening @davidjumani ?

Why not? The URL stays the same. And on the proxy server you can add, remove and/or modify CORS headers if needed.

@ravening
Copy link
Member

I don't think it'll work due to CORS issues esp if website is served under https.
What do you think @wido @GabrielBrascher @weizhouapache @utchoang @svenvogel @ravening @davidjumani ?

Why not? The URL stays the same. And on the proxy server you can add, remove and/or modify CORS headers if needed.

@wido @rhtyd @utchoang

The request is getting blocked. Not sure if im missing but I just added the entire endpoint in config.json

Screenshot 2021-01-12 at 11 11 49

Screenshot 2021-01-12 at 11 13 16
Screenshot 2021-01-12 at 11 13 35

@rohityadavcloud
Copy link
Member

@wido I think it should be the reverse proxy/lb config doing the LB for available/up mgmt servers than provide option in UI. But I see your use-case.

@utchoang
Copy link
Author

utchoang commented Jan 12, 2021

@ravening Yes. If we using domain with http it'll not work due to CORS issues :(. But if using https, It'll works

@weizhouapache
Copy link
Member

@ravening Yes. If we using domain with http it'll not work due to CORS issues :(. But if using https, It'll works

@utchoang both http/https do not work for me, even if I install browser extension to unblock CORS.
it is not an issue with this PR.
the official release 1.0 does not work either. @rhtyd

@utchoang
Copy link
Author

@ravening @weizhouapache @rhtyd @ravening I have tested it a few times with http and https but it both doesn't work due to CORS. This PR doesn't solve the problem.
Do you have a better way?

@wido
Copy link
Contributor

wido commented Jan 13, 2021

I tried this with two management servers from the PCextreme cloud.

server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html;
    }
    location /api/ams {
        # http://127.0.0.1:8080 should be replaced your CloudStack management
        # Server's actual URI
        proxy_pass   https://api.XXXXX.eu/ams3;
    }
    location /api/haa {
        # http://127.0.0.1:8080 should be replaced your CloudStack management
        # Server's actual URI
        proxy_pass   https://api.XXXXX.eu/zone01_haa01;
    }
}
{
  "servers": [
    {
      "name": "Amsterdam",
      "apiBase": "/api/ams"
    },
    {
      "name": "Haarlem",
      "apiBase": "/api/haa"
    }
  ],

I see the requests go to the proper Management server, but my Firefox console complains that sessionkey cookie expires right away.

The calls which I see:

172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "POST /api/haa/ HTTP/1.1" 200 323 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?listall=true&command=listZones&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?username=admin&command=listUsers&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?command=listApis&response=json HTTP/1.1" 401 125 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"

So some calls work, but others get back a 401 Unauthorized. Still unclear to me what is breaking it here.

Both API endpoints and up at the management servers:

wido@wido-laptop:~$ curl -I http://localhost:8181/api/ams
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:08 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block

wido@wido-laptop:~$ curl -I http://localhost:8181/api/haa
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:11 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block
X-Xss-Protection: 1; mode=block

wido@wido-laptop:~$ 

I also checked the management server logs:

2021-01-13 14:26:34,987 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===START===  92.XXX.170.138 -- POST  
2021-01-13 14:26:34,988 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Session cookie is marked secure!
2021-01-13 14:26:34,993 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Attempting to log in user: admin in domain 1
2021-01-13 14:26:34,995 DEBUG [o.a.c.s.a.PBKDF2UserAuthenticator] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Retrieving user: admin
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) CIDRs from which account 'Acct[ae43e7cb-abe2-11ea-8f22-d8252d74bd58-admin]' is allowed to perform API calls: 0.0.0.0/0,::/0
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) User: admin in domain 1 has successfully logged in
2021-01-13 14:26:35,329 INFO  [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Current user logged in under UTC timezone
2021-01-13 14:26:35,329 INFO  [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Timezone offset from UTC is: 0.0
2021-01-13 14:26:35,333 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===END===  92.XXX.170.138 -- POST  
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41) (logid:343a1d0e) ===START===  92.XXX.170.138 -- GET  listall=true&command=listZones&response=json
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServer] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) Expired session, missing signature, or missing apiKey -- ignoring request. Signature: null, apiKey: null
2021-01-13 14:26:35,389 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) ===END===  92.xxx.170.138 -- GET  listall=true&command=listZones&response=json

Noticed how these values are null:

  • apiKey
  • signature

@weizhouapache
Copy link
Member

I tried this with two management servers from the PCextreme cloud.

server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ams {
# http://127.0.0.1:8080 should be replaced your CloudStack management
# Server's actual URI
proxy_pass https://api.XXXXX.eu/ams3;
}
location /api/haa {
# http://127.0.0.1:8080 should be replaced your CloudStack management
# Server's actual URI
proxy_pass https://api.XXXXX.eu/zone01_haa01;
}
}
{
"servers": [
{
"name": "Amsterdam",
"apiBase": "/api/ams"
},
{
"name": "Haarlem",
"apiBase": "/api/haa"
}
],
I see the requests go to the proper Management server, but my Firefox console complains that sessionkey cookie expires right away.

The calls which I see:

172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "POST /api/haa/ HTTP/1.1" 200 323 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?listall=true&command=listZones&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?username=admin&command=listUsers&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?command=listApis&response=json HTTP/1.1" 401 125 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
So some calls work, but others get back a 401 Unauthorized. Still unclear to me what is breaking it here.

Both API endpoints and up at the management servers:

wido@wido-laptop:~$ curl -I http://localhost:8181/api/ams
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:08 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block

wido@wido-laptop:~$ curl -I http://localhost:8181/api/haa
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:11 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block
X-Xss-Protection: 1; mode=block

wido@wido-laptop:~$
I also checked the management server logs:

2021-01-13 14:26:34,987 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===START=== 92.XXX.170.138 -- POST
2021-01-13 14:26:34,988 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Session cookie is marked secure!
2021-01-13 14:26:34,993 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Attempting to log in user: admin in domain 1
2021-01-13 14:26:34,995 DEBUG [o.a.c.s.a.PBKDF2UserAuthenticator] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Retrieving user: admin
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) CIDRs from which account 'Acct[ae43e7cb-abe2-11ea-8f22-d8252d74bd58-admin]' is allowed to perform API calls: 0.0.0.0/0,::/0
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) User: admin in domain 1 has successfully logged in
2021-01-13 14:26:35,329 INFO [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Current user logged in under UTC timezone
2021-01-13 14:26:35,329 INFO [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Timezone offset from UTC is: 0.0
2021-01-13 14:26:35,333 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===END=== 92.XXX.170.138 -- POST
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41) (logid:343a1d0e) ===START=== 92.XXX.170.138 -- GET listall=true&command=listZones&response=json
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServer] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) Expired session, missing signature, or missing apiKey -- ignoring request. Signature: null, apiKey: null
2021-01-13 14:26:35,389 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) ===END=== 92.xxx.170.138 -- GET listall=true&command=listZones&response=json
Noticed how these values are null:

  • apiKey
  • signature

@wido this is a good way to avoid CORS. thanks for sharing.
To set cookie of other domains, you need to enable 3rd-party cookie on server side.
Set-Cookie: SiteSite=None; Secure

if you use nginx, add proxy_cookie_path / "/; Secure; SameSite=None;";
it also means both server and client side must be secure (https)

@wido
Copy link
Contributor

wido commented Jan 14, 2021

I tried this with two management servers from the PCextreme cloud.
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ams {

http://127.0.0.1:8080 should be replaced your CloudStack management

Server's actual URI

proxy_pass https://api.XXXXX.eu/ams3;
}
location /api/haa {

http://127.0.0.1:8080 should be replaced your CloudStack management

Server's actual URI

proxy_pass https://api.XXXXX.eu/zone01_haa01;
}
}
{
"servers": [
{
"name": "Amsterdam",
"apiBase": "/api/ams"
},
{
"name": "Haarlem",
"apiBase": "/api/haa"
}
],
I see the requests go to the proper Management server, but my Firefox console complains that sessionkey cookie expires right away.
The calls which I see:
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "POST /api/haa/ HTTP/1.1" 200 323 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?listall=true&command=listZones&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?username=admin&command=listUsers&response=json HTTP/1.1" 401 126 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
172.17.0.1 - - [13/Jan/2021:13:18:15 +0000] "GET /api/haa/?command=listApis&response=json HTTP/1.1" 401 125 "http://localhost:8181/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
So some calls work, but others get back a 401 Unauthorized. Still unclear to me what is breaking it here.
Both API endpoints and up at the management servers:
wido@wido-laptop:$ curl -I http://localhost:8181/api/ams
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:08 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block
wido@wido-laptop:
$ curl -I http://localhost:8181/api/haa
HTTP/1.1 401 Unauthorized
Server: nginx/1.19.6
Date: Wed, 13 Jan 2021 13:22:11 GMT
Content-Type: text/xml;charset=utf-8
Content-Length: 211
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1;mode=block
content-security-policy: 1
content-security-policy: default-src=none
content-security-policy: script-src=self
content-security-policy: connect-src=self
content-security-policy: img-src=self
content-security-policy: style-src=self
X-Xss-Protection: 1; mode=block
X-Xss-Protection: 1; mode=block
wido@wido-laptop:~$
I also checked the management server logs:
2021-01-13 14:26:34,987 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===START=== 92.XXX.170.138 -- POST
2021-01-13 14:26:34,988 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Session cookie is marked secure!
2021-01-13 14:26:34,993 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Attempting to log in user: admin in domain 1
2021-01-13 14:26:34,995 DEBUG [o.a.c.s.a.PBKDF2UserAuthenticator] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Retrieving user: admin
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) CIDRs from which account 'Acct[ae43e7cb-abe2-11ea-8f22-d8252d74bd58-admin]' is allowed to perform API calls: 0.0.0.0/0,::/0
2021-01-13 14:26:35,316 DEBUG [c.c.u.AccountManagerImpl] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) User: admin in domain 1 has successfully logged in
2021-01-13 14:26:35,329 INFO [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Current user logged in under UTC timezone
2021-01-13 14:26:35,329 INFO [c.c.a.ApiServer] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) Timezone offset from UTC is: 0.0
2021-01-13 14:26:35,333 DEBUG [c.c.a.ApiServlet] (qtp979294118-71298:ctx-a4c4892a) (logid:a706fe0b) ===END=== 92.XXX.170.138 -- POST
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41) (logid:343a1d0e) ===START=== 92.XXX.170.138 -- GET listall=true&command=listZones&response=json
2021-01-13 14:26:35,387 DEBUG [c.c.a.ApiServer] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) Expired session, missing signature, or missing apiKey -- ignoring request. Signature: null, apiKey: null
2021-01-13 14:26:35,389 DEBUG [c.c.a.ApiServlet] (qtp979294118-64148:ctx-2355cc41 ctx-c0c8312c) (logid:343a1d0e) ===END=== 92.xxx.170.138 -- GET listall=true&command=listZones&response=json
Noticed how these values are null:

  • apiKey
  • signature

@wido this is a good way to avoid CORS. thanks for sharing.
To set cookie of other domains, you need to enable 3rd-party cookie on server side.
Set-Cookie: SiteSite=None; Secure

if you use nginx, add proxy_cookie_path / "/; Secure; SameSite=None;";
it also means both server and client side must be secure (https)

This is something I would need to investigate. Haven't been able to do so yet.

@weizhouapache
Copy link
Member

@wido this is a good way to avoid CORS. thanks for sharing.
To set cookie of other domains, you need to enable 3rd-party cookie on server side.
Set-Cookie: SiteSite=None; Secure
if you use nginx, add proxy_cookie_path / "/; Secure; SameSite=None;";
it also means both server and client side must be secure (https)

This is something I would need to investigate. Haven't been able to do so yet.

@wido I have tested it with nginx. it works well.
setting cookie header is supported by haproxy 1.8+

@weizhouapache
Copy link
Member

@utchoang
The only issue is that vm console is not working.
the console always uses /client/console on localhost.
https://github.com/apache/cloudstack-primate/blob/master/src/components/widgets/Console.vue#L21

@wido
Copy link
Contributor

wido commented Jan 15, 2021

@wido this is a good way to avoid CORS. thanks for sharing.
To set cookie of other domains, you need to enable 3rd-party cookie on server side.
Set-Cookie: SiteSite=None; Secure
if you use nginx, add proxy_cookie_path / "/; Secure; SameSite=None;";
it also means both server and client side must be secure (https)

This is something I would need to investigate. Haven't been able to do so yet.

@wido I have tested it with nginx. it works well.
setting cookie header is supported by haproxy 1.8+

Would you be so kind to share your Nginx configuration? This could then also go into the docs of the UI

@rohityadavcloud
Copy link
Member

Given the complexity and that it won't be turnkey (work out the box) - should this be made hidden/pluggable or let the LB handled by the nginx (instead of UI)?

@wido
Copy link
Contributor

wido commented Jan 18, 2021

Given the complexity and that it won't be turnkey (work out the box) - should this be made hidden/pluggable or let the LB handled by the nginx (instead of UI)?

I don't see how the LB can handle this without doing anything in the UI.

If users don't touch the config.json it works as expected. This feature only requires some additions to the Nginx configuration.

It would make presenting the UI to users with multiple management servers much easier.

I haven't tested the latest code yet. @utchoang can you resolve the conflict to make testing easier?

@weizhouapache
Copy link
Member

@wido this is a good way to avoid CORS. thanks for sharing.
To set cookie of other domains, you need to enable 3rd-party cookie on server side.
Set-Cookie: SiteSite=None; Secure
if you use nginx, add proxy_cookie_path / "/; Secure; SameSite=None;";
it also means both server and client side must be secure (https)

This is something I would need to investigate. Haven't been able to do so yet.

@wido I have tested it with nginx. it works well.
setting cookie header is supported by haproxy 1.8+

Would you be so kind to share your Nginx configuration? This could then also go into the docs of the UI

@wido
here are my nginx configurations

(1) config.json on primate server

{
  "servers": [
    {
      "name": "mgt01",
      "apiBase": "/mgt01/client/api"
    },
    {
      "name": "mgt02",
      "apiBase": "/mgt02/client/api"
    },
    {
      "name": "mgt03",
      "apiBase": "/mgt03/client/api"
    }
  ],

(2) nginx config on primate server

server {
    listen                      443 ssl http2;
    server_name                 *.cloud.your.domain;
......
    location / {
......
        location ^~ /mgt01/client {
            rewrite ^/mgt01/(.*)$ /$1 break;
            proxy_pass   https://mgt01.cloud.your.domain;
        }

        location ^~ /mgt02/client {
            rewrite ^/mgt02/(.*)$ /$1 break;
            proxy_pass   https://mgt02.cloud.your.domain;
        }

        location ^~ /mgt03/client {
            rewrite ^/mgt03/(.*)$ /$1 break;
            proxy_pass   https://mgt03.cloud.your.domain;
        }
    }
}

(3) nginx on cloudstack management server

upstream mgtservers {
    hash $request_uri consistent;
    server 10.10.10.10:8080;
}

server {
    listen                      443 ssl http2;
    server_name                 *.cloud.your.domain;
......
    location / {
......
        proxy_pass http://mgtservers;
        proxy_cookie_path / "/; Secure; SameSite=None;";
    }
}

@weizhouapache
Copy link
Member

weizhouapache commented Jan 18, 2021

@wido the above config does not work with latest commit by @utchoang
even if I change the config.json to the following

  "servers": [
    {
      "name": "mgt01",
      "apiHost": "/mgt01",
      "apiBase": "/client/api"
    },
    {
      "name": "mgt02",
      "apiHost": "/mgt02",
      "apiBase": "/client/api"
    },
    {
      "name": "mgt03",
      "apiHost": "/mgt03",
      "apiBase": "/client/api"
    }
  ],

this is fixed by

diff --git a/src/permission.js b/src/permission.js
index d865b43e..201e9b0c 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -42,7 +42,11 @@ router.beforeEach((to, from, next) => {

   const servers = Vue.prototype.$config.servers
   const serverStorage = Vue.ls.get(SERVER_MANAGER)
-  const serverFilter = servers.filter(ser => ser.apiHost + ser.apiBase === serverStorage.apiHost + serverStorage.apiBase)
+  var apiFullPath = null
+  if (serverStorage) {
+    apiFullPath = serverStorage.apiHost + serverStorage.apiBase
+  }
+  const serverFilter = servers.filter(ser => ser.apiHost + ser.apiBase === apiFullPath)
   const server = serverFilter[0] || servers[0]

   Vue.axios.defaults.baseURL = server.apiHost + server.apiBase

@weizhouapache
Copy link
Member

Given the complexity and that it won't be turnkey (work out the box) - should this be made hidden/pluggable or let the LB handled by the nginx (instead of UI)?

I don't see how the LB can handle this without doing anything in the UI.

If users don't touch the config.json it works as expected. This feature only requires some additions to the Nginx configuration.

It would make presenting the UI to users with multiple management servers much easier.

I haven't tested the latest code yet. @utchoang can you resolve the conflict to make testing easier?

agree with @wido
it is a very useful for users who have multiple cloudstack platforms and want to have a centralized management on all platforms.

@utchoang
Copy link
Author

@wido Can you run test again? Thank you.

@weizhouapache
Copy link
Member

@utchoang tested good.

one concern, to keep backwards compatibility, apiHost should be set to "" if it is not found in config.json (there is no apiHost in config.json in primate 1.0.0 or cloudstack 4.15.0.0).

@weizhouapache
Copy link
Member

@utchoang it seems......
config.servers[0].apiHost || '' + config.servers[0].apiBase is equals to
config.servers[0].apiHost || ('' + config.servers[0].apiBase)

@utchoang
Copy link
Author

@weizhouapache This is not true because baseUrl needs a combination of apiHost and apiBase. In your way, if apiHost exists in config.json then baseUrl is only equal to apiHost. I will edit it again to see better

@weizhouapache
Copy link
Member

@utchoang it works with commit "Fix for clear code."

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Multiple Management Server support
6 participants