Commit 43de4993 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch '52363-ui-changes-to-cluster-and-ado-pages' into 'master'

Moves domain setting to Clusters page

Closes #52363

See merge request gitlab-org/gitlab-ce!24580
parents 5fc522ed d9af3752
...@@ -127,6 +127,7 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -127,6 +127,7 @@ class Clusters::ClustersController < Clusters::BaseController
params.require(:cluster).permit( params.require(:cluster).permit(
:enabled, :enabled,
:environment_scope, :environment_scope,
:base_domain,
platform_kubernetes_attributes: [ platform_kubernetes_attributes: [
:namespace :namespace
] ]
...@@ -136,6 +137,7 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -136,6 +137,7 @@ class Clusters::ClustersController < Clusters::BaseController
:enabled, :enabled,
:name, :name,
:environment_scope, :environment_scope,
:base_domain,
platform_kubernetes_attributes: [ platform_kubernetes_attributes: [
:api_url, :api_url,
:token, :token,
......
...@@ -9,41 +9,4 @@ module AutoDevopsHelper ...@@ -9,41 +9,4 @@ module AutoDevopsHelper
!project.repository.gitlab_ci_yml && !project.repository.gitlab_ci_yml &&
!project.ci_service !project.ci_service
end end
def auto_devops_warning_message(project)
if missing_auto_devops_service?(project)
params = {
kubernetes: link_to('Kubernetes cluster', project_clusters_path(project))
}
if missing_auto_devops_domain?(project)
_('Auto Review Apps and Auto Deploy need a domain name and a %{kubernetes} to work correctly.') % params
else
_('Auto Review Apps and Auto Deploy need a %{kubernetes} to work correctly.') % params
end
elsif missing_auto_devops_domain?(project)
_('Auto Review Apps and Auto Deploy need a domain name to work correctly.')
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)
!(project.auto_devops || project.build_auto_devops)&.has_domain?
end
def missing_auto_devops_service?(project)
!project.deployment_platform&.active?
end
end end
...@@ -18,6 +18,7 @@ module Clusters ...@@ -18,6 +18,7 @@ module Clusters
Applications::Knative.application_name => Applications::Knative Applications::Knative.application_name => Applications::Knative
}.freeze }.freeze
DEFAULT_ENVIRONMENT = '*'.freeze DEFAULT_ENVIRONMENT = '*'.freeze
KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN'.freeze
belongs_to :user belongs_to :user
...@@ -49,7 +50,7 @@ module Clusters ...@@ -49,7 +50,7 @@ module Clusters
validates :name, cluster_name: true validates :name, cluster_name: true
validates :cluster_type, presence: 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 :restrict_modification, on: :update
validate :no_groups, unless: :group_type? validate :no_groups, unless: :group_type?
...@@ -65,6 +66,9 @@ module Clusters ...@@ -65,6 +66,9 @@ module Clusters
delegate :available?, to: :application_ingress, prefix: true, allow_nil: true delegate :available?, to: :application_ingress, prefix: true, allow_nil: true
delegate :available?, to: :application_prometheus, 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 :available?, to: :application_knative, prefix: true, allow_nil: true
delegate :external_ip, to: :application_ingress, prefix: true, allow_nil: true
alias_attribute :base_domain, :domain
enum cluster_type: { enum cluster_type: {
instance_type: 1, instance_type: 1,
...@@ -193,8 +197,41 @@ module Clusters ...@@ -193,8 +197,41 @@ module Clusters
project_type? project_type?
end end
def kube_ingress_domain
@kube_ingress_domain ||= domain.presence || instance_domain || legacy_auto_devops_domain
end
def predefined_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless kube_ingress_domain
variables.append(key: KUBE_INGRESS_BASE_DOMAIN, value: kube_ingress_domain)
end
end
private private
def instance_domain
@instance_domain ||= Gitlab::CurrentSettings.auto_devops_domain
end
# To keep backward compatibility with AUTO_DEVOPS_DOMAIN
# environment variable, we need to ensure KUBE_INGRESS_BASE_DOMAIN
# is set if AUTO_DEVOPS_DOMAIN is set on any of the following options:
# ProjectAutoDevops#Domain, project variables or group variables,
# as the AUTO_DEVOPS_DOMAIN is needed for CI_ENVIRONMENT_URL
#
# This method should be removed on 12.0
def legacy_auto_devops_domain
if project_type?
project&.auto_devops&.domain.presence ||
project.variables.find_by(key: 'AUTO_DEVOPS_DOMAIN')&.value.presence ||
project.group&.variables&.find_by(key: 'AUTO_DEVOPS_DOMAIN')&.value.presence
elsif group_type?
group.variables.find_by(key: 'AUTO_DEVOPS_DOMAIN')&.value.presence
end
end
def restrict_modification def restrict_modification
if provider&.on_creation? if provider&.on_creation?
errors.add(:base, "cannot modify during creation") errors.add(:base, "cannot modify during creation")
......
...@@ -98,6 +98,8 @@ module Clusters ...@@ -98,6 +98,8 @@ module Clusters
.append(key: 'KUBE_NAMESPACE', value: actual_namespace) .append(key: 'KUBE_NAMESPACE', value: actual_namespace)
.append(key: 'KUBECONFIG', value: kubeconfig, public: false, file: true) .append(key: 'KUBECONFIG', value: kubeconfig, public: false, file: true)
end end
variables.concat(cluster.predefined_variables)
end end
end end
......
...@@ -24,6 +24,11 @@ class ProjectAutoDevops < ActiveRecord::Base ...@@ -24,6 +24,11 @@ class ProjectAutoDevops < ActiveRecord::Base
domain.present? || instance_domain.present? domain.present? || instance_domain.present?
end 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 on
# https://gitlab.com/gitlab-org/gitlab-ce/issues/52363
def predefined_variables def predefined_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables| Gitlab::Ci::Variables::Collection.new.tap do |variables|
if has_domain? if has_domain?
......
...@@ -20,12 +20,27 @@ ...@@ -20,12 +20,27 @@
.form-text.text-muted= s_("ClusterIntegration|Choose which of your environments will use this cluster.") .form-text.text-muted= s_("ClusterIntegration|Choose which of your environments will use this cluster.")
- else - else
= text_field_tag :environment_scope, '*', class: 'col-md-6 form-control disabled', placeholder: s_('ClusterIntegration|Environment scope'), disabled: true = 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 = help_page_path('user/project/clusters/index', anchor: 'base-domain')
- environment_scope_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: environment_scope_url } - environment_scope_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: environment_scope_url }
.form-text.text-muted .form-text.text-muted
%code * %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 } = 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 :base_domain, class: 'col-md-6 form-control js-select-on-focus'
.form-text.text-muted
- auto_devops_url = help_page_path('topics/autodevops/index')
- 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 matching the domain.').html_safe % { auto_devops_start: auto_devops_start, auto_devops_end: '</a>'.html_safe }
- if @cluster.application_ingress_external_ip.present?
= s_('ClusterIntegration|Alternatively')
%code #{@cluster.application_ingress_external_ip}.nip.io
= s_('ClusterIntegration| can be used instead of a custom domain.')
- custom_domain_url = help_page_path('user/project/clusters/index', anchor: '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| %{custom_domain_start}More information%{custom_domain_end}.').html_safe % { custom_domain_start: custom_domain_start, custom_domain_end: '</a>'.html_safe }
- if can?(current_user, :update_cluster, @cluster) - if can?(current_user, :update_cluster, @cluster)
.form-group .form-group
= field.submit _('Save changes'), class: 'btn btn-success' = field.submit _('Save changes'), class: 'btn btn-success'
...@@ -4,10 +4,6 @@ ...@@ -4,10 +4,6 @@
= form_errors(@project) = form_errors(@project)
%fieldset.builds-feature.js-auto-devops-settings %fieldset.builds-feature.js-auto-devops-settings
.form-group .form-group
- message = auto_devops_warning_message(@project)
- if message
%p.auto-devops-warning-message.settings-message.text-center
= message.html_safe
= f.fields_for :auto_devops_attributes, @auto_devops do |form| = f.fields_for :auto_devops_attributes, @auto_devops do |form|
.card.auto-devops-card .card.auto-devops-card
.card-body .card-body
...@@ -21,19 +17,12 @@ ...@@ -21,19 +17,12 @@
= s_('CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found.') = 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' = link_to _('More information'), help_page_path('topics/autodevops/index.md'), target: '_blank'
.card-footer.js-extra-settings{ class: @project.auto_devops_enabled? || 'hidden' } .card-footer.js-extra-settings{ class: @project.auto_devops_enabled? || 'hidden' }
= form.label :domain do %p.settings-message.text-center
%strong= _('Domain') - kubernetes_cluster_link = help_page_path('user/project/clusters/index')
= form.text_field :domain, class: 'form-control', placeholder: 'domain.com' - kubernetes_cluster_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: kubernetes_cluster_link }
.form-text.text-muted = 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 }
= 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'
%label.prepend-top-10 %label.prepend-top-10
%strong= s_('CICD|Deployment strategy') %strong= s_('CICD|Deployment strategy')
%p.settings-message.text-center
= s_('CICD|Deployment strategy needs a domain name to work correctly.')
.form-check .form-check
= form.radio_button :deploy_strategy, 'continuous', class: 'form-check-input' = form.radio_button :deploy_strategy, 'continuous', class: 'form-check-input'
= form.label :deploy_strategy_continuous, class: 'form-check-label' do = form.label :deploy_strategy_continuous, class: 'form-check-label' do
......
---
title: Moves domain setting from Auto DevOps to Cluster's page
merge_request: 24580
author:
type: added
# frozen_string_literal: true
class MigrateAutoDevOpsDomainToClusterDomain < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
execute(update_clusters_domain_query)
end
def down
# no-op
end
private
def update_clusters_domain_query
if Gitlab::Database.mysql?
mysql_query
else
postgresql_query
end
end
def mysql_query
<<~HEREDOC
UPDATE clusters, project_auto_devops, cluster_projects
SET
clusters.domain = project_auto_devops.domain
WHERE
cluster_projects.cluster_id = clusters.id
AND project_auto_devops.project_id = cluster_projects.project_id
AND project_auto_devops.domain != ''
HEREDOC
end
def postgresql_query
<<~HEREDOC
UPDATE clusters
SET domain = project_auto_devops.domain
FROM cluster_projects, project_auto_devops
WHERE
cluster_projects.cluster_id = clusters.id
AND project_auto_devops.project_id = cluster_projects.project_id
AND project_auto_devops.domain != ''
HEREDOC
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190131122559) do ActiveRecord::Schema.define(version: 20190204115450) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
# #
# In order to deploy, you must have a Kubernetes cluster configured either # In order to deploy, you must have a Kubernetes cluster configured either
# via a project integration, or via group/project variables. # via a project integration, or via group/project variables.
# AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project # KUBE_INGRESS_BASE_DOMAIN must also be set on the cluster settings,
# level, or manually added below. # as a variable at the group or project level, or manually added below.
# #
# Continuous deployment to production is enabled by default. # Continuous deployment to production is enabled by default.
# If you want to deploy to staging first, set STAGING_ENABLED environment variable. # If you want to deploy to staging first, set STAGING_ENABLED environment variable.
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
image: alpine:latest image: alpine:latest
variables: variables:
# AUTO_DEVOPS_DOMAIN is the application deployment domain and should be set as a variable at the group or project level. # KUBE_INGRESS_BASE_DOMAIN is the application deployment domain and should be set as a variable at the group or project level.
# AUTO_DEVOPS_DOMAIN: domain.example.com # KUBE_INGRESS_BASE_DOMAIN: domain.example.com
POSTGRES_USER: user POSTGRES_USER: user
POSTGRES_PASSWORD: testing-password POSTGRES_PASSWORD: testing-password
...@@ -251,7 +251,7 @@ review: ...@@ -251,7 +251,7 @@ review:
- persist_environment_url - persist_environment_url
environment: environment:
name: review/$CI_COMMIT_REF_NAME name: review/$CI_COMMIT_REF_NAME
url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$KUBE_INGRESS_BASE_DOMAIN
on_stop: stop_review on_stop: stop_review
artifacts: artifacts:
paths: [environment_url.txt] paths: [environment_url.txt]
...@@ -306,7 +306,7 @@ staging: ...@@ -306,7 +306,7 @@ staging:
- deploy - deploy
environment: environment:
name: staging name: staging
url: http://$CI_PROJECT_PATH_SLUG-staging.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_INGRESS_BASE_DOMAIN
only: only:
refs: refs:
- master - master
...@@ -330,7 +330,7 @@ canary: ...@@ -330,7 +330,7 @@ canary:
- deploy canary - deploy canary
environment: environment:
name: production name: production
url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
when: manual when: manual
only: only:
refs: refs:
...@@ -354,7 +354,7 @@ canary: ...@@ -354,7 +354,7 @@ canary:
- persist_environment_url - persist_environment_url
environment: environment:
name: production name: production
url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
artifacts: artifacts:
paths: [environment_url.txt] paths: [environment_url.txt]
...@@ -403,7 +403,7 @@ production_manual: ...@@ -403,7 +403,7 @@ production_manual:
- persist_environment_url - persist_environment_url
environment: environment:
name: production name: production
url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
artifacts: artifacts:
paths: [environment_url.txt] paths: [environment_url.txt]
...@@ -689,7 +689,7 @@ rollout 100%: ...@@ -689,7 +689,7 @@ rollout 100%:
--set application.database_url="$DATABASE_URL" \ --set application.database_url="$DATABASE_URL" \
--set application.secretName="$APPLICATION_SECRET_NAME" \ --set application.secretName="$APPLICATION_SECRET_NAME" \
--set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \ --set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \
--set service.commonName="le.$AUTO_DEVOPS_DOMAIN" \ --set service.commonName="le.$KUBE_INGRESS_BASE_DOMAIN" \
--set service.url="$CI_ENVIRONMENT_URL" \ --set service.url="$CI_ENVIRONMENT_URL" \
--set service.additionalHosts="$additional_hosts" \ --set service.additionalHosts="$additional_hosts" \
--set replicaCount="$replicas" \ --set replicaCount="$replicas" \
...@@ -725,7 +725,7 @@ rollout 100%: ...@@ -725,7 +725,7 @@ rollout 100%:
--set application.database_url="$DATABASE_URL" \ --set application.database_url="$DATABASE_URL" \
--set application.secretName="$APPLICATION_SECRET_NAME" \ --set application.secretName="$APPLICATION_SECRET_NAME" \
--set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \ --set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \
--set service.commonName="le.$AUTO_DEVOPS_DOMAIN" \ --set service.commonName="le.$KUBE_INGRESS_BASE_DOMAIN" \
--set service.url="$CI_ENVIRONMENT_URL" \ --set service.url="$CI_ENVIRONMENT_URL" \
--set service.additionalHosts="$additional_hosts" \ --set service.additionalHosts="$additional_hosts" \
--set replicaCount="$replicas" \ --set replicaCount="$replicas" \
...@@ -823,11 +823,24 @@ rollout 100%: ...@@ -823,11 +823,24 @@ rollout 100%:
kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE" kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE"
} }
# Function to ensure backwards compatibility with AUTO_DEVOPS_DOMAIN
function ensure_kube_ingress_base_domain() {
if [ -z ${KUBE_INGRESS_BASE_DOMAIN+x} ]; then
export KUBE_INGRESS_BASE_DOMAIN=$AUTO_DEVOPS_DOMAIN
fi
}
function check_kube_domain() { function check_kube_domain() {
if [ -z ${AUTO_DEVOPS_DOMAIN+x} ]; then ensure_kube_ingress_base_domain
echo "In order to deploy or use Review Apps, AUTO_DEVOPS_DOMAIN variable must be set"
echo "You can do it in Auto DevOps project settings or defining a variable at group or project level" if [ -z ${KUBE_INGRESS_BASE_DOMAIN+x} ]; then
echo "In order to deploy or use Review Apps,"
echo "AUTO_DEVOPS_DOMAIN or KUBE_INGRESS_BASE_DOMAIN variables must be set"
echo "From 11.8, you can set KUBE_INGRESS_BASE_DOMAIN in cluster settings"
echo "or by defining a variable at group or project level."
echo "You can also manually add it in .gitlab-ci.yml" echo "You can also manually add it in .gitlab-ci.yml"
echo "AUTO_DEVOPS_DOMAIN support will be dropped on 12.0"
false false
else else
true true
......
...@@ -123,9 +123,6 @@ msgstr "" ...@@ -123,9 +123,6 @@ msgstr ""
msgid "%{lock_path} is locked by GitLab User %{lock_user_id}" msgid "%{lock_path} is locked by GitLab User %{lock_user_id}"
msgstr "" 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" msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr "" msgstr ""
...@@ -885,15 +882,6 @@ msgstr "" ...@@ -885,15 +882,6 @@ msgstr ""
msgid "Auto DevOps, runners and job artifacts" msgid "Auto DevOps, runners and job artifacts"
msgstr "" msgstr ""
msgid "Auto Review Apps and Auto Deploy need a %{kubernetes} to work correctly."
msgstr ""
msgid "Auto Review Apps and Auto Deploy need a domain name and a %{kubernetes} to work correctly."
msgstr ""
msgid "Auto Review Apps and Auto Deploy need a domain name to work correctly."
msgstr ""
msgid "Auto-cancel redundant, pending pipelines" msgid "Auto-cancel redundant, pending pipelines"
msgstr "" msgstr ""
...@@ -1266,9 +1254,6 @@ msgstr "" ...@@ -1266,9 +1254,6 @@ msgstr ""
msgid "CICD|Deployment strategy" msgid "CICD|Deployment strategy"
msgstr "" msgstr ""
msgid "CICD|Deployment strategy needs a domain name to work correctly."
msgstr ""
msgid "CICD|Jobs" msgid "CICD|Jobs"
msgstr "" msgstr ""
...@@ -1278,7 +1263,7 @@ msgstr "" ...@@ -1278,7 +1263,7 @@ msgstr ""
msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found." msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
msgstr "" 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 "" msgstr ""
msgid "CICD|instance enabled" msgid "CICD|instance enabled"
...@@ -1551,6 +1536,12 @@ msgstr "" ...@@ -1551,6 +1536,12 @@ msgstr ""
msgid "Closed (moved)" msgid "Closed (moved)"
msgstr "" msgstr ""
msgid "ClusterIntegration| %{custom_domain_start}More information%{custom_domain_end}."
msgstr ""
msgid "ClusterIntegration| can be used instead of a custom domain."
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}" 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 "" msgstr ""
...@@ -1581,6 +1572,9 @@ msgstr "" ...@@ -1581,6 +1572,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}" 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 "" msgstr ""
msgid "ClusterIntegration|Alternatively"
msgstr ""
msgid "ClusterIntegration|An error occured while trying to fetch project zones: %{error}" msgid "ClusterIntegration|An error occured while trying to fetch project zones: %{error}"
msgstr "" msgstr ""
...@@ -1602,6 +1596,9 @@ msgstr "" ...@@ -1602,6 +1596,9 @@ msgstr ""
msgid "ClusterIntegration|Are you sure you want to remove this Kubernetes cluster's integration? This will not delete your actual Kubernetes cluster." msgid "ClusterIntegration|Are you sure you want to remove this Kubernetes cluster's integration? This will not delete your actual Kubernetes cluster."
msgstr "" msgstr ""
msgid "ClusterIntegration|Base domain"
msgstr ""
msgid "ClusterIntegration|CA Certificate" msgid "ClusterIntegration|CA Certificate"
msgstr "" msgstr ""
...@@ -1926,6 +1923,9 @@ msgstr "" ...@@ -1926,6 +1923,9 @@ msgstr ""
msgid "ClusterIntegration|Something went wrong while installing %{title}" msgid "ClusterIntegration|Something went wrong while installing %{title}"
msgstr "" 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 matching the domain."
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." 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 "" msgstr ""
......
...@@ -13,9 +13,7 @@ module QA # rubocop:disable Naming/FileName ...@@ -13,9 +13,7 @@ module QA # rubocop:disable Naming/FileName
view 'app/views/projects/settings/ci_cd/_autodevops_form.html.haml' do 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 :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 :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 element :save_changes_button, "submit _('Save changes')" # rubocop:disable QA/ElementWithPattern
end end
...@@ -31,10 +29,9 @@ module QA # rubocop:disable Naming/FileName ...@@ -31,10 +29,9 @@ module QA # rubocop:disable Naming/FileName
end end
end end
def enable_auto_devops_with_domain(domain) def enable_auto_devops
expand_section(:autodevops_settings) do expand_section(:autodevops_settings) do
check 'Default to Auto DevOps pipeline' check 'Default to Auto DevOps pipeline'
fill_in 'Domain', with: domain
click_on 'Save changes' click_on 'Save changes'
end end
end end
......
...@@ -6,12 +6,16 @@ module QA ...@@ -6,12 +6,16 @@ module QA
module Resource module Resource
class KubernetesCluster < Base class KubernetesCluster < Base
attr_writer :project, :cluster, 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 attribute :ingress_ip do
Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip) Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip)
end end
attribute :domain do
"#{ingress_ip}.nip.io"
end
def fabricate! def fabricate!
@project.visit! @project.visit!
......
...@@ -52,13 +52,13 @@ module QA ...@@ -52,13 +52,13 @@ module QA
end end
kubernetes_cluster.populate(:ingress_ip) kubernetes_cluster.populate(:ingress_ip)
@project.visit! @project.visit!
Page::Project::Menu.act { click_ci_cd_settings } Page::Project::Menu.act { click_ci_cd_settings }
Page::Project::Settings::CICD.perform do |p| Page::Project::Settings::CICD.perform do |p|
p.enable_auto_devops_with_domain( p.enable_auto_devops
"#{kubernetes_cluster.ingress_ip}.nip.io")
end end
kubernetes_cluster.populate(:domain)
end end
after(:all) do after(:all) do
......
...@@ -429,12 +429,14 @@ describe Groups::ClustersController do ...@@ -429,12 +429,14 @@ describe Groups::ClustersController do
end end
let(:cluster) { create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [group]) } let(:cluster) { create(:cluster, :provided_by_user, cluster_type: :group_type, groups: [group]) }
let(:domain) { 'test-domain.com' }
let(:params) do let(:params) do
{ {
cluster: { cluster: {
enabled: false, enabled: false,
name: 'my-new-cluster-name' name: 'my-new-cluster-name',
base_domain: domain
} }
} }
end end
...@@ -447,6 +449,20 @@ describe Groups::ClustersController do ...@@ -447,6 +449,20 @@ describe Groups::ClustersController do
expect(flash[:notice]).to eq('Kubernetes cluster was successfully updated.') expect(flash[:notice]).to eq('Kubernetes cluster was successfully updated.')
expect(cluster.enabled).to be_falsey expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name') 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 end
context 'when format is json' do context 'when format is json' do
...@@ -456,7 +472,8 @@ describe Groups::ClustersController do ...@@ -456,7 +472,8 @@ describe Groups::ClustersController do
{ {
cluster: { cluster: {
enabled: false, enabled: false,
name: 'my-new-cluster-name' name: 'my-new-cluster-name',
domain: domain
} }
} }
end end
......
# 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_base_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).not_to have_content('can be used instead of a custom domain.')
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
...@@ -98,14 +98,12 @@ describe "Projects > Settings > Pipelines settings" do ...@@ -98,14 +98,12 @@ describe "Projects > Settings > Pipelines settings" do
expect(page).not_to have_content('instance enabled') expect(page).not_to have_content('instance enabled')
expect(find_field('project_auto_devops_attributes_enabled')).not_to be_checked expect(find_field('project_auto_devops_attributes_enabled')).not_to be_checked
check 'Default to Auto DevOps pipeline' check 'Default to Auto DevOps pipeline'
fill_in('project_auto_devops_attributes_domain', with: 'test.com')
click_on 'Save changes' click_on 'Save changes'
end end
expect(page.status_code).to eq(200) expect(page.status_code).to eq(200)
expect(project.auto_devops).to be_present expect(project.auto_devops).to be_present
expect(project.auto_devops).to be_enabled expect(project.auto_devops).to be_enabled
expect(project.auto_devops.domain).to eq('test.com')
page.within '#autodevops-settings' do page.within '#autodevops-settings' do
expect(find_field('project_auto_devops_attributes_enabled')).to be_checked expect(find_field('project_auto_devops_attributes_enabled')).to be_checked
...@@ -113,29 +111,6 @@ describe "Projects > Settings > Pipelines settings" do ...@@ -113,29 +111,6 @@ describe "Projects > Settings > Pipelines settings" do
end end
end 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 end
describe 'runners registration token' do describe 'runners registration token' do
......
...@@ -90,39 +90,4 @@ describe AutoDevopsHelper do ...@@ -90,39 +90,4 @@ describe AutoDevopsHelper do
it { is_expected.to eq(false) } it { is_expected.to eq(false) }
end end
end end
describe '.auto_devops_warning_message' do
subject { helper.auto_devops_warning_message(project) }
context 'when the service is missing' do
before do
allow(helper).to receive(:missing_auto_devops_service?).and_return(true)
end
context 'when the domain is missing' do
before do
allow(helper).to receive(:missing_auto_devops_domain?).and_return(true)
end
it { is_expected.to match(/Auto Review Apps and Auto Deploy need a domain name and a .* to work correctly./) }
end
context 'when the domain is not missing' do
before do
allow(helper).to receive(:missing_auto_devops_domain?).and_return(false)
end
it { is_expected.to match(/Auto Review Apps and Auto Deploy need a .* to work correctly./) }
end
end
context 'when the domain is missing' do
before do
allow(helper).to receive(:missing_auto_devops_service?).and_return(false)
allow(helper).to receive(:missing_auto_devops_domain?).and_return(true)
end
it { is_expected.to eq('Auto Review Apps and Auto Deploy need a domain name to work correctly.') }
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20190204115450_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: 25, domain: nil)
end
it 'should only update specific cluster projects' do
migrate!
expect(clusters_with_domain.count).to eq(20)
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
expect(clusters_without_domain.count).to eq(25)
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|
specific_domain = "#{cluster_project.id}-#{domain}" if domain
project_auto_devops_table.create(
project_id: cluster_project.project_id,
enabled: true,
domain: specific_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
...@@ -30,6 +30,7 @@ describe Clusters::Cluster do ...@@ -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_ingress).with_prefix }
it { is_expected.to delegate_method(:available?).to(:application_prometheus).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(: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 } it { is_expected.to respond_to :project }
...@@ -514,4 +515,108 @@ describe Clusters::Cluster do ...@@ -514,4 +515,108 @@ describe Clusters::Cluster do
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
end end
describe '#kube_ingress_domain' do
let(:cluster) { create(:cluster, :provided_by_gcp) }
subject { cluster.kube_ingress_domain }
context 'with domain set in cluster' do
let(:cluster) { create(:cluster, :provided_by_gcp, :with_domain) }
it { is_expected.to eq(cluster.domain) }
end
context 'with no domain on cluster' do
context 'with a project cluster' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
context 'with domain set at instance level' do
before do
stub_application_setting(auto_devops_domain: 'global_domain.com')
it { is_expected.to eq('global_domain.com') }
end
end
context 'with domain set on ProjectAutoDevops' do
before do
auto_devops = project.build_auto_devops(domain: 'legacy-ado-domain.com')
auto_devops.save
end
it { is_expected.to eq('legacy-ado-domain.com') }
end
context 'with domain set as environment variable on project' do
before do
variable = project.variables.build(key: 'AUTO_DEVOPS_DOMAIN', value: 'project-ado-domain.com')
variable.save
end
it { is_expected.to eq('project-ado-domain.com') }
end
context 'with domain set as environment variable on the group project' do
let(:group) { create(:group) }
before do
project.update(parent_id: group.id)
variable = group.variables.build(key: 'AUTO_DEVOPS_DOMAIN', value: 'group-ado-domain.com')
variable.save
end
it { is_expected.to eq('group-ado-domain.com') }
end
end
context 'with a group cluster' do
let(:cluster) { create(:cluster, :group, :provided_by_gcp) }
context 'with domain set as environment variable for the group' do
let(:group) { cluster.group }
before do
variable = group.variables.build(key: 'AUTO_DEVOPS_DOMAIN', value: 'group-ado-domain.com')
variable.save
end
it { is_expected.to eq('group-ado-domain.com') }
end
end
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, :provided_by_gcp, :project) }
it 'should return an empty array' do
expect(subject.to_hash).to be_empty
end
end
end
end end
...@@ -297,6 +297,19 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching ...@@ -297,6 +297,19 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
end end
end 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 end
describe '#terminals' do describe '#terminals' do
......
...@@ -7,56 +7,9 @@ describe 'projects/settings/ci_cd/_autodevops_form' do ...@@ -7,56 +7,9 @@ describe 'projects/settings/ci_cd/_autodevops_form' do
assign :project, project assign :project, project
end end
context 'when kubernetes is not active' do it 'shows a warning message about Kubernetes cluster' do
context 'when auto devops domain is not defined' do render
it 'shows warning message' do
render
expect(rendered).to have_css('.auto-devops-warning-message') expect(rendered).to have_text('You must add a Kubernetes cluster integration to this project with a domain in order for your deployment strategy to work correctly.')
expect(rendered).to have_text('Auto Review Apps and Auto Deploy need a domain name and a')
expect(rendered).to have_link('Kubernetes cluster')
end
end
context 'when auto devops domain is defined' do
before do
project.build_auto_devops(domain: 'example.com')
end
it 'shows warning message' do
render
expect(rendered).to have_css('.auto-devops-warning-message')
expect(rendered).to have_text('Auto Review Apps and Auto Deploy need a')
expect(rendered).to have_link('Kubernetes cluster')
end
end
end
context 'when kubernetes is active' do
before do
create(:kubernetes_service, project: project)
end
context 'when auto devops domain is not defined' do
it 'shows warning message' do
render
expect(rendered).to have_css('.auto-devops-warning-message')
expect(rendered).to have_text('Auto Review Apps and Auto Deploy need a domain name to work correctly.')
end
end
context 'when auto devops domain is defined' do
before do
project.build_auto_devops(domain: 'example.com')
end
it 'does not show warning message' do
render
expect(rendered).not_to have_css('.auto-devops-warning-message')
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment