summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayra Cabrera <mcabrera@gitlab.com>2019-01-23 10:28:19 -0600
committerMayra Cabrera <mcabrera@gitlab.com>2019-02-04 11:43:34 -0600
commit8ff73614a1466ffc39e4464462719e7456c03e29 (patch)
tree8573da7dc5ea258c1aa7bd373b757b4b0e6cf996
parent280b6f6f8d038c4c28b32c5965e8a052adf4a052 (diff)
downloadgitlab-ce-8ff73614a1466ffc39e4464462719e7456c03e29.tar.gz
Moves domain setting to Cluster setting
Changes domain field to be on the Cluster page show, removing it from Auto DevOps setting. Also injects the new environment variable KUBE_INGRESS_BASE_DOMAIN into kubernetes#predefined_variables. Migration to move the information from ProjectAutoDevops#domain to Clusters::Cluster#domain. As well as necessary modifications to qa selectors Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/52363
-rw-r--r--app/controllers/clusters/clusters_controller.rb2
-rw-r--r--app/helpers/auto_devops_helper.rb11
-rw-r--r--app/models/clusters/cluster.rb19
-rw-r--r--app/models/clusters/platforms/kubernetes.rb2
-rw-r--r--app/models/project_auto_devops.rb3
-rw-r--r--app/views/clusters/clusters/_form.html.haml18
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml13
-rw-r--r--changelogs/unreleased/52363-ui-changes-to-cluster-and-ado-pages.yml5
-rw-r--r--db/migrate/20190129165720_migrate_auto_dev_ops_domain_to_cluster_domain.rb78
-rw-r--r--locale/gitlab.pot20
-rw-r--r--qa/qa/page/project/settings/ci_cd.rb5
-rw-r--r--qa/qa/resource/kubernetes_cluster.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb6
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb21
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb69
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb25
-rw-r--r--spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb100
-rw-r--r--spec/models/clusters/cluster_spec.rb59
-rw-r--r--spec/models/clusters/platforms/kubernetes_spec.rb13
19 files changed, 421 insertions, 62 deletions
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index b9717b97640..483842fe456 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -127,6 +127,7 @@ class Clusters::ClustersController < Clusters::BaseController
params.require(:cluster).permit(
:enabled,
:environment_scope,
+ :domain,
platform_kubernetes_attributes: [
:namespace
]
@@ -136,6 +137,7 @@ class Clusters::ClustersController < Clusters::BaseController
:enabled,
:name,
:environment_scope,
+ :domain,
platform_kubernetes_attributes: [
:api_url,
:token,
diff --git a/app/helpers/auto_devops_helper.rb b/app/helpers/auto_devops_helper.rb
index 516c8a353ea..8628c90dc51 100644
--- a/app/helpers/auto_devops_helper.rb
+++ b/app/helpers/auto_devops_helper.rb
@@ -26,17 +26,6 @@ module AutoDevopsHelper
end
end
- # rubocop: disable CodeReuse/ActiveRecord
- def cluster_ingress_ip(project)
- project
- .cluster_ingresses
- .where("external_ip is not null")
- .limit(1)
- .pluck(:external_ip)
- .first
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
private
def missing_auto_devops_domain?(project)
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index a2c48973fa5..2b677961df5 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -49,7 +49,7 @@ module Clusters
validates :name, cluster_name: true
validates :cluster_type, presence: true
- validates :domain, allow_nil: true, hostname: { allow_numeric_hostname: true, require_valid_tld: true }
+ validates :domain, allow_blank: true, hostname: { allow_numeric_hostname: true, require_valid_tld: true }
validate :restrict_modification, on: :update
validate :no_groups, unless: :group_type?
@@ -65,6 +65,7 @@ module Clusters
delegate :available?, to: :application_ingress, prefix: true, allow_nil: true
delegate :available?, to: :application_prometheus, prefix: true, allow_nil: true
delegate :available?, to: :application_knative, prefix: true, allow_nil: true
+ delegate :external_ip, to: :application_ingress, prefix: true, allow_nil: true
enum cluster_type: {
instance_type: 1,
@@ -193,8 +194,24 @@ module Clusters
project_type?
end
+ def has_domain?
+ domain.present? || instance_domain.present?
+ end
+
+ def predefined_variables
+ Gitlab::Ci::Variables::Collection.new.tap do |variables|
+ break variables unless has_domain?
+
+ variables.append(key: 'KUBE_INGRESS_BASE_DOMAIN', value: domain.presence || instance_domain)
+ end
+ end
+
private
+ def instance_domain
+ Gitlab::CurrentSettings.auto_devops_domain
+ end
+
def restrict_modification
if provider&.on_creation?
errors.add(:base, "cannot modify during creation")
diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb
index 8f3424db295..c8969351ed9 100644
--- a/app/models/clusters/platforms/kubernetes.rb
+++ b/app/models/clusters/platforms/kubernetes.rb
@@ -98,6 +98,8 @@ module Clusters
.append(key: 'KUBE_NAMESPACE', value: actual_namespace)
.append(key: 'KUBECONFIG', value: kubeconfig, public: false, file: true)
end
+
+ variables.concat(cluster.predefined_variables)
end
end
diff --git a/app/models/project_auto_devops.rb b/app/models/project_auto_devops.rb
index 2253ad7b543..d254ec158ca 100644
--- a/app/models/project_auto_devops.rb
+++ b/app/models/project_auto_devops.rb
@@ -24,6 +24,9 @@ class ProjectAutoDevops < ActiveRecord::Base
domain.present? || instance_domain.present?
end
+ # From 11.8, AUTO_DEVOPS_DOMAIN has been replaced by KUBE_INGRESS_BASE_DOMAIN.
+ # See Clusters::Cluster#predefined_variables and https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/24580
+ # for more info. Support for AUTO_DEVOPS_DOMAIN support will be dropped on 12.0.
def predefined_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
if has_domain?
diff --git a/app/views/clusters/clusters/_form.html.haml b/app/views/clusters/clusters/_form.html.haml
index 4c47e11927e..068f14364ec 100644
--- a/app/views/clusters/clusters/_form.html.haml
+++ b/app/views/clusters/clusters/_form.html.haml
@@ -20,12 +20,28 @@
.form-text.text-muted= s_("ClusterIntegration|Choose which of your environments will use this cluster.")
- else
= text_field_tag :environment_scope, '*', class: 'col-md-6 form-control disabled', placeholder: s_('ClusterIntegration|Environment scope'), disabled: true
- - environment_scope_url = 'https://docs.gitlab.com/ee/user/project/clusters/#setting-the-environment-scope-premium'
+ - environment_scope_url = 'https://docs.gitlab.com/ee/user/project/clusters/#base-domain'
- environment_scope_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: environment_scope_url }
.form-text.text-muted
%code *
= s_("ClusterIntegration| is the default environment scope for this cluster. This means that all jobs, regardless of their environment, will use this cluster. %{environment_scope_start}More information%{environment_scope_end}").html_safe % { environment_scope_start: environment_scope_start, environment_scope_end: '</a>'.html_safe }
+ .form-group
+ %h5= s_('ClusterIntegration|Base domain')
+ = field.text_field :domain, class: 'col-md-6 form-control js-select-on-focus'
+ .form-text.text-muted
+ - if @cluster.application_ingress_external_ip.present?
+ - auto_devops_url = 'https://docs.gitlab.com/ee/topics/autodevops/'
+ - auto_devops_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: auto_devops_url }
+ = s_('ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured to the Ingress IP Address below.').html_safe % { auto_devops_start: auto_devops_start, auto_devops_end: '</a>'.html_safe }
+ = s_('ClusterIntegration|Alternatively')
+ %code #{@cluster.application_ingress_external_ip}.nip.io
+ - custom_domain_url = 'https://docs.gitlab.com/ee/user/project/clusters/#pointing-your-dns-at-the-cluster-ip'
+ - custom_domain_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: custom_domain_url }
+ = s_('ClusterIntegration| can be used instead of a custom domain. %{custom_domain_start}More information%{custom_domain_end}').html_safe % { custom_domain_start: custom_domain_start, custom_domain_end: '</a>'.html_safe }
+ - else
+ = s_('ClusterIntegration|Before setting a domain, you must first install Ingress on your cluster below.')
+
- if can?(current_user, :update_cluster, @cluster)
.form-group
= field.submit _('Save changes'), class: 'btn btn-success'
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index 5ec5a06396e..c2bbcf8fcaf 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -21,15 +21,10 @@
= s_('CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found.')
= link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank'
.card-footer.js-extra-settings{ class: @project.auto_devops_enabled? || 'hidden' }
- = form.label :domain do
- %strong= _('Domain')
- = form.text_field :domain, class: 'form-control', placeholder: 'domain.com'
- .form-text.text-muted
- = s_('CICD|You need to specify a domain if you want to use Auto Review Apps and Auto Deploy stages.')
- - if cluster_ingress_ip = cluster_ingress_ip(@project)
- = s_('%{nip_domain} can be used as an alternative to a custom domain.').html_safe % { nip_domain: "<code>#{cluster_ingress_ip}.nip.io</code>".html_safe }
- = link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'auto-devops-base-domain'), target: '_blank'
-
+ %p.settings-message.text-center
+ - kubernetes_cluster_link = 'https://docs.gitlab.com/ee/user/project/clusters/'
+ - kubernetes_cluster_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: kubernetes_cluster_link }
+ = s_('CICD|You must add a %{kubernetes_cluster_start}Kubernetes cluster integration%{kubernetes_cluster_end} to this project with a domain in order for your deployment strategy to work correctly.').html_safe % { kubernetes_cluster_start: kubernetes_cluster_start, kubernetes_cluster_end: '</a>'.html_safe }
%label.prepend-top-10
%strong= s_('CICD|Deployment strategy')
%p.settings-message.text-center
diff --git a/changelogs/unreleased/52363-ui-changes-to-cluster-and-ado-pages.yml b/changelogs/unreleased/52363-ui-changes-to-cluster-and-ado-pages.yml
new file mode 100644
index 00000000000..25f01f95177
--- /dev/null
+++ b/changelogs/unreleased/52363-ui-changes-to-cluster-and-ado-pages.yml
@@ -0,0 +1,5 @@
+---
+title: Moves domain setting to cluster page
+merge_request: 24580
+author:
+type: added
diff --git a/db/migrate/20190129165720_migrate_auto_dev_ops_domain_to_cluster_domain.rb b/db/migrate/20190129165720_migrate_auto_dev_ops_domain_to_cluster_domain.rb
new file mode 100644
index 00000000000..2d3e9acaa62
--- /dev/null
+++ b/db/migrate/20190129165720_migrate_auto_dev_ops_domain_to_cluster_domain.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+class MigrateAutoDevOpsDomainToClusterDomain < ActiveRecord::Migration[5.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ domains_info = connection.exec_query(project_auto_devops_query).rows
+ domains_info.each_slice(1_000) do |batch|
+ update_clusters_query = build_clusters_query(Hash[*batch.flatten])
+
+ connection.exec_query(update_clusters_query)
+ end
+ end
+
+ def down
+ # no-op
+ end
+
+ private
+
+ def project_auto_devops_table
+ @project_auto_devops_table ||= ProjectAutoDevops.arel_table
+ end
+
+ def cluster_projects_table
+ @cluster_projects_table ||= Clusters::Project.arel_table
+ end
+
+ # Fetches ProjectAutoDevops records with:
+ # - A domain set
+ # - With a Clusters::Project related to Project
+ #
+ # Returns an array of arrays like:
+ # => [
+ # [177, "104.198.38.135.nip.io"],
+ # [178, "35.232.213.111.nip.io"],
+ # ...
+ # ]
+ # Where the first element is the Cluster ID and
+ # the second element is the domain.
+ def project_auto_devops_query
+ project_auto_devops_table.join(cluster_projects_table, Arel::Nodes::OuterJoin)
+ .on(project_auto_devops_table[:project_id].eq(cluster_projects_table[:project_id]))
+ .where(project_auto_devops_table[:domain].not_eq(nil).and(project_auto_devops_table[:domain].not_eq('')))
+ .project(cluster_projects_table[:cluster_id], project_auto_devops_table[:domain])
+ .to_sql
+ end
+
+ # Returns an SQL UPDATE query using a CASE statement
+ # to update multiple cluster rows with different values.
+ #
+ # Example:
+ # UPDATE clusters
+ # SET domain = (CASE
+ # WHEN id = 177 then '104.198.38.135.nip.io'
+ # WHEN id = 178 then '35.232.213.111.nip.io'
+ # WHEN id = 179 then '35.232.168.149.nip.io'
+ # WHEN id = 180 then '35.224.116.88.nip.io'
+ # END)
+ # WHERE id IN (177,178,179,180);
+ def build_clusters_query(cluster_domains_info)
+ <<~HEREDOC
+ UPDATE clusters
+ SET domain = (CASE
+ #{cluster_when_statements(cluster_domains_info)}
+ END)
+ WHERE id IN (#{cluster_domains_info.keys.join(",")});
+ HEREDOC
+ end
+
+ def cluster_when_statements(cluster_domains_info)
+ cluster_domains_info.map do |cluster_id, domain|
+ "WHEN id = #{cluster_id} then '#{domain}'"
+ end.join("\n")
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ccdbc63c51e..8600e6fa394 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -138,9 +138,6 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr ""
-msgid "%{nip_domain} can be used as an alternative to a custom domain."
-msgstr ""
-
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr ""
@@ -1236,7 +1233,7 @@ msgstr ""
msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
msgstr ""
-msgid "CICD|You need to specify a domain if you want to use Auto Review Apps and Auto Deploy stages."
+msgid "CICD|You must add a %{kubernetes_cluster_start}Kubernetes cluster integration%{kubernetes_cluster_end} to this project with a domain in order for your deployment strategy to work correctly."
msgstr ""
msgid "CICD|instance enabled"
@@ -1509,6 +1506,9 @@ msgstr ""
msgid "Closed (moved)"
msgstr ""
+msgid "ClusterIntegration| can be used instead of a custom domain. %{custom_domain_start}More information%{custom_domain_end}"
+msgstr ""
+
msgid "ClusterIntegration| is the default environment scope for this cluster. This means that all jobs, regardless of their environment, will use this cluster. %{environment_scope_start}More information%{environment_scope_end}"
msgstr ""
@@ -1539,6 +1539,9 @@ msgstr ""
msgid "ClusterIntegration|After installing Ingress, you will need to point your wildcard DNS at the generated external IP address in order to view your app after it is deployed. %{ingressHelpLink}"
msgstr ""
+msgid "ClusterIntegration|Alternatively"
+msgstr ""
+
msgid "ClusterIntegration|An error occured while trying to fetch project zones: %{error}"
msgstr ""
@@ -1560,6 +1563,12 @@ msgstr ""
msgid "ClusterIntegration|Are you sure you want to remove this Kubernetes cluster's integration? This will not delete your actual Kubernetes cluster."
msgstr ""
+msgid "ClusterIntegration|Base domain"
+msgstr ""
+
+msgid "ClusterIntegration|Before setting a domain, you must first install Ingress on your cluster below."
+msgstr ""
+
msgid "ClusterIntegration|CA Certificate"
msgstr ""
@@ -1884,6 +1893,9 @@ msgstr ""
msgid "ClusterIntegration|Something went wrong while installing %{title}"
msgstr ""
+msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured to the Ingress IP Address below."
+msgstr ""
+
msgid "ClusterIntegration|The IP address is in the process of being assigned. Please check your Kubernetes cluster or Quotas on Google Kubernetes Engine if it takes a long time."
msgstr ""
diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb
index 12c2409a5a7..2de39b8ebf5 100644
--- a/qa/qa/page/project/settings/ci_cd.rb
+++ b/qa/qa/page/project/settings/ci_cd.rb
@@ -13,9 +13,7 @@ module QA # rubocop:disable Naming/FileName
view 'app/views/projects/settings/ci_cd/_autodevops_form.html.haml' do
element :enable_auto_devops_field, 'check_box :enabled' # rubocop:disable QA/ElementWithPattern
- element :domain_field, 'text_field :domain' # rubocop:disable QA/ElementWithPattern
element :enable_auto_devops_button, "%strong= s_('CICD|Default to Auto DevOps pipeline')" # rubocop:disable QA/ElementWithPattern
- element :domain_input, "%strong= _('Domain')" # rubocop:disable QA/ElementWithPattern
element :save_changes_button, "submit _('Save changes')" # rubocop:disable QA/ElementWithPattern
end
@@ -31,10 +29,9 @@ module QA # rubocop:disable Naming/FileName
end
end
- def enable_auto_devops_with_domain(domain)
+ def enable_auto_devops
expand_section(:autodevops_settings) do
check 'Default to Auto DevOps pipeline'
- fill_in 'Domain', with: domain
click_on 'Save changes'
end
end
diff --git a/qa/qa/resource/kubernetes_cluster.rb b/qa/qa/resource/kubernetes_cluster.rb
index d67e5f6da20..19c6dc8890d 100644
--- a/qa/qa/resource/kubernetes_cluster.rb
+++ b/qa/qa/resource/kubernetes_cluster.rb
@@ -6,10 +6,14 @@ module QA
module Resource
class KubernetesCluster < Base
attr_writer :project, :cluster,
- :install_helm_tiller, :install_ingress, :install_prometheus, :install_runner
+ :install_helm_tiller, :install_ingress, :install_prometheus, :install_runner, :domain
attribute :ingress_ip do
- Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip)
+ ingress_ip_value
+ end
+
+ attribute :domain do
+ "#{ingress_ip_value}.nip.io"
end
def fabricate!
@@ -52,6 +56,12 @@ module QA
end
end
end
+
+ private
+
+ def ingress_ip_value
+ @ingress_ip_value ||= Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip)
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index b0ff83db86b..5c8ec465143 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -52,13 +52,13 @@ module QA
end
kubernetes_cluster.populate(:ingress_ip)
-
@project.visit!
Page::Project::Menu.act { click_ci_cd_settings }
Page::Project::Settings::CICD.perform do |p|
- p.enable_auto_devops_with_domain(
- "#{kubernetes_cluster.ingress_ip}.nip.io")
+ p.enable_auto_devops
end
+
+ kubernetes_cluster.populate(:domain)
end
after(:all) do
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 0f28499194e..d5a149a57df 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -429,12 +429,14 @@ describe Groups::ClustersController do
end
let(:cluster) { create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [group]) }
+ let(:domain) { 'test-domain.com' }
let(:params) do
{
cluster: {
enabled: false,
- name: 'my-new-cluster-name'
+ name: 'my-new-cluster-name',
+ domain: domain
}
}
end
@@ -447,6 +449,20 @@ describe Groups::ClustersController do
expect(flash[:notice]).to eq('Kubernetes cluster was successfully updated.')
expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name')
+ expect(cluster.domain).to eq('test-domain.com')
+ end
+
+ context 'when domain is invalid' do
+ let(:domain) { 'not-a-valid-domain' }
+
+ it 'should not update cluster attributes' do
+ go
+
+ cluster.reload
+ expect(response).to render_template(:show)
+ expect(cluster.name).not_to eq('my-new-cluster-name')
+ expect(cluster.domain).not_to eq('test-domain.com')
+ end
end
context 'when format is json' do
@@ -456,7 +472,8 @@ describe Groups::ClustersController do
{
cluster: {
enabled: false,
- name: 'my-new-cluster-name'
+ name: 'my-new-cluster-name',
+ domain: domain
}
}
end
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
new file mode 100644
index 00000000000..844008f841a
--- /dev/null
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Clusterable > Show page' do
+ let(:current_user) { create(:user) }
+
+ before do
+ sign_in(current_user)
+ end
+
+ shared_examples 'editing domain' do
+ before do
+ clusterable.add_maintainer(current_user)
+ end
+
+ it 'allow the user to set domain' do
+ visit cluster_path
+
+ within '#cluster-integration' do
+ fill_in('cluster_domain', with: 'test.com')
+ click_on 'Save changes'
+ end
+
+ expect(page.status_code).to eq(200)
+ expect(page).to have_content('Kubernetes cluster was successfully updated.')
+ end
+
+ context 'when there is a cluster with ingress and external ip' do
+ before do
+ cluster.create_application_ingress!(external_ip: '192.168.1.100')
+
+ visit cluster_path
+ end
+
+ it 'shows help text with the domain as an alternative to custom domain' do
+ within '#cluster-integration' do
+ expect(page).to have_content('Alternatively 192.168.1.100.nip.io can be used instead of a custom domain')
+ end
+ end
+ end
+
+ context 'when there is no ingress' do
+ it 'alternative to custom domain is not shown' do
+ visit cluster_path
+
+ within '#cluster-integration' do
+ expect(page).to have_content('Before setting a domain, you must first install Ingress on your cluster below.')
+ end
+ end
+ end
+ end
+
+ context 'when clusterable is a project' do
+ it_behaves_like 'editing domain' do
+ let(:clusterable) { create(:project) }
+ let(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [clusterable]) }
+ let(:cluster_path) { project_cluster_path(clusterable, cluster) }
+ end
+ end
+
+ context 'when clusterable is a group' do
+ it_behaves_like 'editing domain' do
+ let(:clusterable) { create(:group) }
+ let(:cluster) { create(:cluster, :provided_by_gcp, :group, groups: [clusterable]) }
+ let(:cluster_path) { group_cluster_path(clusterable, cluster) }
+ end
+ end
+end
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index 6f8ec0015ad..4c85abe9971 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -98,14 +98,12 @@ describe "Projects > Settings > Pipelines settings" do
expect(page).not_to have_content('instance enabled')
expect(find_field('project_auto_devops_attributes_enabled')).not_to be_checked
check 'Default to Auto DevOps pipeline'
- fill_in('project_auto_devops_attributes_domain', with: 'test.com')
click_on 'Save changes'
end
expect(page.status_code).to eq(200)
expect(project.auto_devops).to be_present
expect(project.auto_devops).to be_enabled
- expect(project.auto_devops.domain).to eq('test.com')
page.within '#autodevops-settings' do
expect(find_field('project_auto_devops_attributes_enabled')).to be_checked
@@ -113,29 +111,6 @@ describe "Projects > Settings > Pipelines settings" do
end
end
end
-
- context 'when there is a cluster with ingress and external_ip' do
- before do
- cluster = create(:cluster, projects: [project])
- cluster.create_application_ingress!(external_ip: '192.168.1.100')
- end
-
- it 'shows the help text with the nip.io domain as an alternative to custom domain' do
- visit project_settings_ci_cd_path(project)
- expect(page).to have_content('192.168.1.100.nip.io can be used as an alternative to a custom domain')
- end
- end
-
- context 'when there is no ingress' do
- before do
- create(:cluster, projects: [project])
- end
-
- it 'alternative to custom domain is not shown' do
- visit project_settings_ci_cd_path(project)
- expect(page).not_to have_content('can be used as an alternative to a custom domain')
- end
- end
end
describe 'runners registration token' do
diff --git a/spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb b/spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb
new file mode 100644
index 00000000000..09013ee4bd0
--- /dev/null
+++ b/spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb
@@ -0,0 +1,100 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20190129165720_migrate_auto_dev_ops_domain_to_cluster_domain.rb')
+
+describe MigrateAutoDevOpsDomainToClusterDomain, :migration do
+ include MigrationHelpers::ClusterHelpers
+
+ let(:migration) { described_class.new }
+ let(:project_auto_devops_table) { table(:project_auto_devops) }
+ let(:clusters_table) { table(:clusters) }
+ let(:cluster_projects_table) { table(:cluster_projects) }
+
+ # Following lets are needed by MigrationHelpers::ClusterHelpers
+ let(:cluster_kubernetes_namespaces_table) { table(:clusters_kubernetes_namespaces) }
+ let(:projects_table) { table(:projects) }
+ let(:namespaces_table) { table(:namespaces) }
+ let(:provider_gcp_table) { table(:cluster_providers_gcp) }
+ let(:platform_kubernetes_table) { table(:cluster_platforms_kubernetes) }
+
+ before do
+ setup_cluster_projects_with_domain(quantity: 20, domain: domain)
+ end
+
+ context 'with ProjectAutoDevOps with no domain' do
+ let(:domain) { nil }
+
+ it 'should not update cluster project' do
+ migrate!
+
+ expect(clusters_without_domain.count).to eq(clusters_table.count)
+ end
+ end
+
+ context 'with ProjectAutoDevOps with domain' do
+ let(:domain) { 'example-domain.com' }
+
+ it 'should update all cluster projects' do
+ migrate!
+
+ expect(clusters_with_domain.count).to eq(clusters_table.count)
+ end
+ end
+
+ context 'when only some ProjectAutoDevOps have domain set' do
+ let(:domain) { 'example-domain.com' }
+
+ before do
+ setup_cluster_projects_with_domain(quantity: 20, domain: nil)
+ end
+
+ it 'should only update specific cluster projects' do
+ migrate!
+
+ project_auto_devops_with_domain.each do |project_auto_devops|
+ cluster_project = Clusters::Project.find_by(project_id: project_auto_devops.project_id)
+ cluster = Clusters::Cluster.find(cluster_project.cluster_id)
+
+ expect(cluster.domain).to be_present
+ end
+
+ project_auto_devops_without_domain.each do |project_auto_devops|
+ cluster_project = Clusters::Project.find_by(project_id: project_auto_devops.project_id)
+ cluster = Clusters::Cluster.find(cluster_project.cluster_id)
+
+ expect(cluster.domain).not_to be_present
+ end
+ end
+ end
+
+ def setup_cluster_projects_with_domain(quantity:, domain:)
+ create_cluster_project_list(quantity)
+
+ cluster_projects = cluster_projects_table.last(quantity)
+
+ cluster_projects.each do |cluster_project|
+ project_auto_devops_table.create(
+ project_id: cluster_project.project_id,
+ enabled: true,
+ domain: domain
+ )
+ end
+ end
+
+ def project_auto_devops_with_domain
+ project_auto_devops_table.where.not("domain IS NULL OR domain = ''")
+ end
+
+ def project_auto_devops_without_domain
+ project_auto_devops_table.where("domain IS NULL OR domain = ''")
+ end
+
+ def clusters_with_domain
+ clusters_table.where.not("domain IS NULL OR domain = ''")
+ end
+
+ def clusters_without_domain
+ clusters_table.where("domain IS NULL OR domain = ''")
+ end
+end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 0161db740ee..abef586d258 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -30,6 +30,7 @@ describe Clusters::Cluster do
it { is_expected.to delegate_method(:available?).to(:application_ingress).with_prefix }
it { is_expected.to delegate_method(:available?).to(:application_prometheus).with_prefix }
it { is_expected.to delegate_method(:available?).to(:application_knative).with_prefix }
+ it { is_expected.to delegate_method(:external_ip).to(:application_ingress).with_prefix }
it { is_expected.to respond_to :project }
@@ -514,4 +515,62 @@ describe Clusters::Cluster do
it { is_expected.to be_falsey }
end
end
+
+ describe '#has_domain?' do
+ subject { cluster.has_domain? }
+
+ context 'with domain set at instance level' do
+ let(:cluster) { create(:cluster, :provided_by_gcp) }
+
+ before do
+ stub_application_setting(auto_devops_domain: 'global_domain.com')
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'with domain set in cluster' do
+ let(:cluster) { create(:cluster, :provided_by_gcp, :with_domain) }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when domain is not set at instance level nor in cluster' do
+ let(:cluster) { create(:cluster, :provided_by_gcp) }
+
+ it { is_expected.to be_falsy }
+ end
+ end
+
+ describe '#predefined_variables' do
+ subject { cluster.predefined_variables }
+
+ context 'with an instance domain' do
+ let(:cluster) { create(:cluster, :provided_by_gcp) }
+
+ before do
+ stub_application_setting(auto_devops_domain: 'global_domain.com')
+ end
+
+ it 'should include KUBE_INGRESS_BASE_DOMAIN' do
+ expect(subject.to_hash).to include(KUBE_INGRESS_BASE_DOMAIN: 'global_domain.com')
+ end
+ end
+
+ context 'with a cluster domain' do
+ let(:cluster) { create(:cluster, :provided_by_gcp, domain: 'example.com') }
+
+ it 'should include KUBE_INGRESS_BASE_DOMAIN' do
+ expect(subject.to_hash).to include(KUBE_INGRESS_BASE_DOMAIN: 'example.com')
+ end
+ end
+
+ context 'with no domain' do
+ let(:cluster) { create(:cluster) }
+
+ it 'should return an empty array' do
+ expect(subject.to_hash).to be_empty
+ end
+ end
+ end
end
diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb
index 6c8a223092e..c273fa7e164 100644
--- a/spec/models/clusters/platforms/kubernetes_spec.rb
+++ b/spec/models/clusters/platforms/kubernetes_spec.rb
@@ -297,6 +297,19 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
end
end
end
+
+ context 'with a domain' do
+ let!(:cluster) do
+ create(:cluster, :provided_by_gcp, :with_domain,
+ platform_kubernetes: kubernetes)
+ end
+
+ it 'sets KUBE_INGRESS_BASE_DOMAIN' do
+ expect(subject).to include(
+ { key: 'KUBE_INGRESS_BASE_DOMAIN', value: cluster.domain, public: true }
+ )
+ end
+ end
end
describe '#terminals' do