/spec/requests/api/internal/pages_spec.rb

https://gitlab.com/rymai/gitlab · Ruby · 257 lines · 210 code · 46 blank · 1 comment · 0 complexity · 61bd619227a762ca9093cc04fff05d65 MD5 · raw file

  1. # frozen_string_literal: true
  2. require 'spec_helper'
  3. describe API::Internal::Pages do
  4. describe "GET /internal/pages" do
  5. let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) }
  6. before do
  7. allow(Gitlab::Pages).to receive(:secret).and_return(pages_secret)
  8. end
  9. def query_host(host, headers = {})
  10. get api("/internal/pages"), headers: headers, params: { host: host }
  11. end
  12. context 'feature flag disabled' do
  13. before do
  14. stub_feature_flags(pages_internal_api: false)
  15. end
  16. it 'responds with 404 Not Found' do
  17. query_host('pages.gitlab.io')
  18. expect(response).to have_gitlab_http_status(:not_found)
  19. end
  20. end
  21. context 'feature flag enabled' do
  22. context 'not authenticated' do
  23. it 'responds with 401 Unauthorized' do
  24. query_host('pages.gitlab.io')
  25. expect(response).to have_gitlab_http_status(:unauthorized)
  26. end
  27. end
  28. context 'authenticated' do
  29. def query_host(host)
  30. jwt_token = JWT.encode({ 'iss' => 'gitlab-pages' }, Gitlab::Pages.secret, 'HS256')
  31. headers = { Gitlab::Pages::INTERNAL_API_REQUEST_HEADER => jwt_token }
  32. super(host, headers)
  33. end
  34. def deploy_pages(project)
  35. project.mark_pages_as_deployed
  36. end
  37. context 'domain does not exist' do
  38. it 'responds with 204 no content' do
  39. query_host('pages.gitlab.io')
  40. expect(response).to have_gitlab_http_status(:no_content)
  41. expect(response.body).to be_empty
  42. end
  43. end
  44. context 'serverless domain' do
  45. let(:namespace) { create(:namespace, name: 'gitlab-org') }
  46. let(:project) { create(:project, namespace: namespace, name: 'gitlab-ce') }
  47. let(:environment) { create(:environment, project: project) }
  48. let(:pages_domain) { create(:pages_domain, domain: 'serverless.gitlab.io') }
  49. let(:knative_without_ingress) { create(:clusters_applications_knative) }
  50. let(:knative_with_ingress) { create(:clusters_applications_knative, external_ip: '10.0.0.1') }
  51. context 'without a knative ingress gateway IP' do
  52. let!(:serverless_domain_cluster) do
  53. create(
  54. :serverless_domain_cluster,
  55. uuid: 'abcdef12345678',
  56. pages_domain: pages_domain,
  57. knative: knative_without_ingress
  58. )
  59. end
  60. let(:serverless_domain) do
  61. create(
  62. :serverless_domain,
  63. serverless_domain_cluster: serverless_domain_cluster,
  64. environment: environment
  65. )
  66. end
  67. it 'responds with 204 no content' do
  68. query_host(serverless_domain.uri.host)
  69. expect(response).to have_gitlab_http_status(:no_content)
  70. expect(response.body).to be_empty
  71. end
  72. end
  73. context 'with a knative ingress gateway IP' do
  74. let!(:serverless_domain_cluster) do
  75. create(
  76. :serverless_domain_cluster,
  77. uuid: 'abcdef12345678',
  78. pages_domain: pages_domain,
  79. knative: knative_with_ingress
  80. )
  81. end
  82. let(:serverless_domain) do
  83. create(
  84. :serverless_domain,
  85. serverless_domain_cluster: serverless_domain_cluster,
  86. environment: environment
  87. )
  88. end
  89. it 'responds with proxy configuration' do
  90. query_host(serverless_domain.uri.host)
  91. expect(response).to have_gitlab_http_status(:ok)
  92. expect(response).to match_response_schema('internal/serverless/virtual_domain')
  93. expect(json_response['certificate']).to eq(pages_domain.certificate)
  94. expect(json_response['key']).to eq(pages_domain.key)
  95. expect(json_response['lookup_paths']).to eq(
  96. [
  97. {
  98. 'source' => {
  99. 'type' => 'serverless',
  100. 'service' => "test-function.#{project.name}-#{project.id}-#{environment.slug}.#{serverless_domain_cluster.knative.hostname}",
  101. 'cluster' => {
  102. 'hostname' => serverless_domain_cluster.knative.hostname,
  103. 'address' => serverless_domain_cluster.knative.external_ip,
  104. 'port' => 443,
  105. 'cert' => serverless_domain_cluster.certificate,
  106. 'key' => serverless_domain_cluster.key
  107. }
  108. }
  109. }
  110. ]
  111. )
  112. end
  113. end
  114. end
  115. context 'custom domain' do
  116. let(:namespace) { create(:namespace, name: 'gitlab-org') }
  117. let(:project) { create(:project, namespace: namespace, name: 'gitlab-ce') }
  118. let!(:pages_domain) { create(:pages_domain, domain: 'pages.io', project: project) }
  119. context 'when there are no pages deployed for the related project' do
  120. it 'responds with 204 No Content' do
  121. query_host('pages.io')
  122. expect(response).to have_gitlab_http_status(:no_content)
  123. end
  124. end
  125. context 'when there are pages deployed for the related project' do
  126. it 'domain lookup is case insensitive' do
  127. deploy_pages(project)
  128. query_host('Pages.IO')
  129. expect(response).to have_gitlab_http_status(:ok)
  130. end
  131. it 'responds with the correct domain configuration' do
  132. deploy_pages(project)
  133. query_host('pages.io')
  134. expect(response).to have_gitlab_http_status(:ok)
  135. expect(response).to match_response_schema('internal/pages/virtual_domain')
  136. expect(json_response['certificate']).to eq(pages_domain.certificate)
  137. expect(json_response['key']).to eq(pages_domain.key)
  138. expect(json_response['lookup_paths']).to eq(
  139. [
  140. {
  141. 'project_id' => project.id,
  142. 'access_control' => false,
  143. 'https_only' => false,
  144. 'prefix' => '/',
  145. 'source' => {
  146. 'type' => 'file',
  147. 'path' => 'gitlab-org/gitlab-ce/public/'
  148. }
  149. }
  150. ]
  151. )
  152. end
  153. end
  154. end
  155. context 'namespaced domain' do
  156. let(:group) { create(:group, name: 'mygroup') }
  157. before do
  158. allow(Settings.pages).to receive(:host).and_return('gitlab-pages.io')
  159. allow(Gitlab.config.pages).to receive(:url).and_return("http://gitlab-pages.io")
  160. end
  161. context 'regular project' do
  162. it 'responds with the correct domain configuration' do
  163. project = create(:project, group: group, name: 'myproject')
  164. deploy_pages(project)
  165. query_host('mygroup.gitlab-pages.io')
  166. expect(response).to have_gitlab_http_status(:ok)
  167. expect(response).to match_response_schema('internal/pages/virtual_domain')
  168. expect(json_response['lookup_paths']).to eq(
  169. [
  170. {
  171. 'project_id' => project.id,
  172. 'access_control' => false,
  173. 'https_only' => false,
  174. 'prefix' => '/myproject/',
  175. 'source' => {
  176. 'type' => 'file',
  177. 'path' => 'mygroup/myproject/public/'
  178. }
  179. }
  180. ]
  181. )
  182. end
  183. end
  184. context 'group root project' do
  185. it 'responds with the correct domain configuration' do
  186. project = create(:project, group: group, name: 'mygroup.gitlab-pages.io')
  187. deploy_pages(project)
  188. query_host('mygroup.gitlab-pages.io')
  189. expect(response).to have_gitlab_http_status(:ok)
  190. expect(response).to match_response_schema('internal/pages/virtual_domain')
  191. expect(json_response['lookup_paths']).to eq(
  192. [
  193. {
  194. 'project_id' => project.id,
  195. 'access_control' => false,
  196. 'https_only' => false,
  197. 'prefix' => '/',
  198. 'source' => {
  199. 'type' => 'file',
  200. 'path' => 'mygroup/mygroup.gitlab-pages.io/public/'
  201. }
  202. }
  203. ]
  204. )
  205. end
  206. end
  207. end
  208. end
  209. end
  210. end
  211. end