diff options
25 files changed, 474 insertions, 532 deletions
diff --git a/app/assets/javascripts/pages/projects/clusters/gcp/login/index.js b/app/assets/javascripts/pages/projects/clusters/gcp/login/index.js deleted file mode 100644 index 0c2d7d7c96a..00000000000 --- a/app/assets/javascripts/pages/projects/clusters/gcp/login/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import gcpSignupOffer from '~/clusters/components/gcp_signup_offer'; - -gcpSignupOffer(); diff --git a/app/assets/javascripts/pages/projects/clusters/new/index.js b/app/assets/javascripts/pages/projects/clusters/new/index.js deleted file mode 100644 index 0c2d7d7c96a..00000000000 --- a/app/assets/javascripts/pages/projects/clusters/new/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import gcpSignupOffer from '~/clusters/components/gcp_signup_offer'; - -gcpSignupOffer(); diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js index de1e13de7e9..0658ae8ec23 100644 --- a/app/assets/javascripts/pages/projects/index.js +++ b/app/assets/javascripts/pages/projects/index.js @@ -1,7 +1,21 @@ +import gcpSignupOffer from '~/clusters/components/gcp_signup_offer'; +import initGkeDropdowns from '~/projects/gke_cluster_dropdowns'; import Project from './project'; import ShortcutsNavigation from '../../shortcuts_navigation'; document.addEventListener('DOMContentLoaded', () => { + const page = document.body.dataset.page; + const newClusterViews = [ + 'projects:clusters:new', + 'projects:clusters:create_gcp', + 'projects:clusters:create_user', + ]; + + if (newClusterViews.indexOf(page) > -1) { + gcpSignupOffer(); + initGkeDropdowns(); + } + new Project(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new }); diff --git a/app/controllers/projects/clusters/gcp_controller.rb b/app/controllers/projects/clusters/gcp_controller.rb deleted file mode 100644 index c2c5ad61e01..00000000000 --- a/app/controllers/projects/clusters/gcp_controller.rb +++ /dev/null @@ -1,76 +0,0 @@ -class Projects::Clusters::GcpController < Projects::ApplicationController - before_action :authorize_read_cluster! - before_action :authorize_create_cluster!, only: [:new, :create] - before_action :authorize_google_api, except: :login - helper_method :token_in_session - - def login - begin - state = generate_session_key_redirect(gcp_new_namespace_project_clusters_path.to_s) - - @authorize_url = GoogleApi::CloudPlatform::Client.new( - nil, callback_google_api_auth_url, - state: state).authorize_url - rescue GoogleApi::Auth::ConfigMissingError - # no-op - end - end - - def new - @cluster = ::Clusters::Cluster.new.tap do |cluster| - cluster.build_provider_gcp - end - end - - def create - @cluster = ::Clusters::CreateService - .new(project, current_user, create_params) - .execute(token_in_session) - - if @cluster.persisted? - redirect_to project_cluster_path(project, @cluster) - else - render :new - end - end - - private - - def create_params - params.require(:cluster).permit( - :enabled, - :name, - :environment_scope, - provider_gcp_attributes: [ - :gcp_project_id, - :zone, - :num_nodes, - :machine_type - ]).merge( - provider_type: :gcp, - platform_type: :kubernetes - ) - end - - def authorize_google_api - unless GoogleApi::CloudPlatform::Client.new(token_in_session, nil) - .validate_token(expires_at_in_session) - redirect_to action: 'login' - end - end - - def token_in_session - session[GoogleApi::CloudPlatform::Client.session_key_for_token] - end - - def expires_at_in_session - @expires_at_in_session ||= - session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] - end - - def generate_session_key_redirect(uri) - GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key| - session[key] = uri - end - end -end diff --git a/app/controllers/projects/clusters/user_controller.rb b/app/controllers/projects/clusters/user_controller.rb deleted file mode 100644 index d0db64b2fa9..00000000000 --- a/app/controllers/projects/clusters/user_controller.rb +++ /dev/null @@ -1,40 +0,0 @@ -class Projects::Clusters::UserController < Projects::ApplicationController - before_action :authorize_read_cluster! - before_action :authorize_create_cluster!, only: [:new, :create] - - def new - @cluster = ::Clusters::Cluster.new.tap do |cluster| - cluster.build_platform_kubernetes - end - end - - def create - @cluster = ::Clusters::CreateService - .new(project, current_user, create_params) - .execute - - if @cluster.persisted? - redirect_to project_cluster_path(project, @cluster) - else - render :new - end - end - - private - - def create_params - params.require(:cluster).permit( - :enabled, - :name, - :environment_scope, - platform_kubernetes_attributes: [ - :namespace, - :api_url, - :token, - :ca_cert - ]).merge( - provider_type: :user, - platform_type: :kubernetes - ) - end -end diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index d58039b7d42..62193257940 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -1,10 +1,15 @@ class Projects::ClustersController < Projects::ApplicationController - before_action :cluster, except: [:index, :new] + before_action :cluster, except: [:index, :new, :create_gcp, :create_user] before_action :authorize_read_cluster! + before_action :generate_gcp_authorize_url, only: [:new] + before_action :validate_gcp_token, only: [:new] + before_action :gcp_cluster, only: [:new] + before_action :user_cluster, only: [:new] before_action :authorize_create_cluster!, only: [:new] before_action :authorize_update_cluster!, only: [:update] before_action :authorize_admin_cluster!, only: [:destroy] before_action :update_applications_status, only: [:status] + helper_method :token_in_session STATUS_POLLING_INTERVAL = 10_000 @@ -64,6 +69,38 @@ class Projects::ClustersController < Projects::ApplicationController end end + def create_gcp + @gcp_cluster = ::Clusters::CreateService + .new(project, current_user, create_gcp_cluster_params) + .execute(token_in_session) + + if @gcp_cluster.persisted? + redirect_to project_cluster_path(project, @gcp_cluster) + else + generate_gcp_authorize_url + validate_gcp_token + user_cluster + + render :new, locals: { active_tab: 'gcp' } + end + end + + def create_user + @user_cluster = ::Clusters::CreateService + .new(project, current_user, create_user_cluster_params) + .execute(token_in_session) + + if @user_cluster.persisted? + redirect_to project_cluster_path(project, @user_cluster) + else + generate_gcp_authorize_url + validate_gcp_token + gcp_cluster + + render :new, locals: { active_tab: 'user' } + end + end + private def cluster @@ -95,6 +132,80 @@ class Projects::ClustersController < Projects::ApplicationController end end + def create_gcp_cluster_params + params.require(:cluster).permit( + :enabled, + :name, + :environment_scope, + provider_gcp_attributes: [ + :gcp_project_id, + :zone, + :num_nodes, + :machine_type + ]).merge( + provider_type: :gcp, + platform_type: :kubernetes + ) + end + + def create_user_cluster_params + params.require(:cluster).permit( + :enabled, + :name, + :environment_scope, + platform_kubernetes_attributes: [ + :namespace, + :api_url, + :token, + :ca_cert + ]).merge( + provider_type: :user, + platform_type: :kubernetes + ) + end + + def generate_gcp_authorize_url + state = generate_session_key_redirect(new_project_cluster_path(@project).to_s) + + @authorize_url = GoogleApi::CloudPlatform::Client.new( + nil, callback_google_api_auth_url, + state: state).authorize_url + rescue GoogleApi::Auth::ConfigMissingError + # no-op + end + + def gcp_cluster + @gcp_cluster = ::Clusters::Cluster.new.tap do |cluster| + cluster.build_provider_gcp + end + end + + def user_cluster + @user_cluster = ::Clusters::Cluster.new.tap do |cluster| + cluster.build_platform_kubernetes + end + end + + def validate_gcp_token + @valid_gcp_token = GoogleApi::CloudPlatform::Client.new(token_in_session, nil) + .validate_token(expires_at_in_session) + end + + def token_in_session + session[GoogleApi::CloudPlatform::Client.session_key_for_token] + end + + def expires_at_in_session + @expires_at_in_session ||= + session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] + end + + def generate_session_key_redirect(uri) + GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key| + session[key] = uri + end + end + def authorize_update_cluster! access_denied! unless can?(current_user, :update_cluster, cluster) end diff --git a/app/views/projects/clusters/_dropdown.html.haml b/app/views/projects/clusters/_dropdown.html.haml deleted file mode 100644 index d55a9c60b64..00000000000 --- a/app/views/projects/clusters/_dropdown.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%h4.prepend-top-0= s_('ClusterIntegration|Choose how to set up Kubernetes cluster integration') - -.dropdown.clusters-dropdown - %button.dropdown-menu-toggle.dropdown-menu-full-width{ type: 'button', data: { toggle: 'dropdown' }, 'aria-haspopup': true, 'aria-expanded': false } - %span.dropdown-toggle-text - = dropdown_text - = icon('chevron-down') - %ul.dropdown-menu.clusters-dropdown-menu.dropdown-menu-full-width - %li - = link_to(s_('ClusterIntegration|Create Kubernetes cluster on Google Kubernetes Engine'), gcp_new_namespace_project_clusters_path(@project.namespace, @project)) - %li - = link_to(s_('ClusterIntegration|Add an existing Kubernetes cluster'), user_new_namespace_project_clusters_path(@project.namespace, @project)) diff --git a/app/views/projects/clusters/gcp/_form.html.haml b/app/views/projects/clusters/gcp/_form.html.haml index b8e40b0a38b..0a2e320556d 100644 --- a/app/views/projects/clusters/gcp/_form.html.haml +++ b/app/views/projects/clusters/gcp/_form.html.haml @@ -10,8 +10,10 @@ - link_to_help_page = link_to(s_('ClusterIntegration|help page'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') = s_('ClusterIntegration|Read our %{link_to_help_page} on Kubernetes cluster integration.').html_safe % { link_to_help_page: link_to_help_page} -= form_for @cluster, html: { class: 'js-gke-cluster-creation prepend-top-20', data: { token: token_in_session } }, url: gcp_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field| - = form_errors(@cluster) +%p= link_to('Select a different Google account', @authorize_url) + += form_for @gcp_cluster, html: { class: 'js-gke-cluster-creation prepend-top-20', data: { token: token_in_session } }, url: create_gcp_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field| + = form_errors(@gcp_cluster) .form-group = field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light' = field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name') @@ -19,7 +21,7 @@ = field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-light' = field.text_field :environment_scope, class: 'form-control', readonly: !has_multiple_clusters?(@project), placeholder: s_('ClusterIntegration|Environment scope') - = field.fields_for :provider_gcp, @cluster.provider_gcp do |provider_gcp_field| + = field.fields_for :provider_gcp, @gcp_cluster.provider_gcp do |provider_gcp_field| .form-group = provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project'), class: 'label-light' .js-gcp-project-id-dropdown-entry-point{ data: { docsUrl: 'https://console.cloud.google.com/home/dashboard' } } diff --git a/app/views/projects/clusters/gcp/_header.html.haml b/app/views/projects/clusters/gcp/_header.html.haml index fa989943492..a2ad3cd64df 100644 --- a/app/views/projects/clusters/gcp/_header.html.haml +++ b/app/views/projects/clusters/gcp/_header.html.haml @@ -1,4 +1,4 @@ -%h4.prepend-top-20 +%h4 = s_('ClusterIntegration|Enter the details for your Kubernetes cluster') %p = s_('ClusterIntegration|Please make sure that your Google account meets the following requirements:') diff --git a/app/views/projects/clusters/gcp/login.html.haml b/app/views/projects/clusters/gcp/login.html.haml deleted file mode 100644 index 96c7a648676..00000000000 --- a/app/views/projects/clusters/gcp/login.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -- breadcrumb_title 'Kubernetes' -- page_title _("Login") - -= render_gcp_signup_offer - -.row.prepend-top-default - .col-sm-4 - = render 'projects/clusters/sidebar' - .col-sm-8 - = render 'projects/clusters/dropdown', dropdown_text: s_('ClusterIntegration|Create Kubernetes cluster on Google Kubernetes Engine') - = render 'header' -.row - .col-sm-8.offset-sm-4.signin-with-google - - if @authorize_url - = link_to(image_tag('auth_buttons/signin_with_google.png', width: '191px'), @authorize_url) - = _('or') - = link_to('create a new Google account', 'https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.cloud.google.com%2Ffreetrial%3Futm_campaign%3D2018_cpanel%26utm_source%3Dgitlab%26utm_medium%3Dreferral', target: '_blank', rel: 'noopener noreferrer') - - else - .settings-message.text-center - - link = link_to(s_('ClusterIntegration|properly configured'), help_page_path("integration/google"), target: '_blank', rel: 'noopener noreferrer') - = s_('Google authentication is not %{link_to_documentation}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_to_documentation: link } diff --git a/app/views/projects/clusters/gcp/new.html.haml b/app/views/projects/clusters/gcp/new.html.haml deleted file mode 100644 index ea78d66d883..00000000000 --- a/app/views/projects/clusters/gcp/new.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -- breadcrumb_title 'Kubernetes' -- page_title _("New Kubernetes Cluster") - -.row.prepend-top-default - .col-sm-4 - = render 'projects/clusters/sidebar' - .col-sm-8 - = render 'projects/clusters/dropdown', dropdown_text: s_('ClusterIntegration|Create Kubernetes cluster on Google Kubernetes Engine') - = render 'header' - = render 'form' diff --git a/app/views/projects/clusters/new.html.haml b/app/views/projects/clusters/new.html.haml index 828e2a84753..a38003f5750 100644 --- a/app/views/projects/clusters/new.html.haml +++ b/app/views/projects/clusters/new.html.haml @@ -1,15 +1,36 @@ - breadcrumb_title 'Kubernetes' - page_title _("Kubernetes Cluster") +- active_tab = local_assigns.fetch(:active_tab, 'gcp') += javascript_include_tag 'https://apis.google.com/js/api.js' = render_gcp_signup_offer .row.prepend-top-default - .col-sm-4 + .col-md-3 = render 'sidebar' - .col-sm-8 - %h4.prepend-top-0= s_('ClusterIntegration|Choose how to set up Kubernetes cluster integration') + .col-md-9.js-toggle-container + %ul.nav-links.nav-tabs.gitlab-tabs.nav{ role: 'tablist' } + %li.nav-item{ role: 'presentation' } + %a.nav-link{ href: '#create-gcp-cluster-pane', id: 'create-gcp-cluster-tab', class: active_when(active_tab == 'gcp'), data: { toggle: 'tab' }, role: 'tab' } + %span Create new Cluster on GKE + %li.nav-item{ role: 'presentation' } + %a.nav-link{ href: '#add-user-cluster-pane', id: 'add-user-cluster-tab', class: active_when(active_tab == 'user'), data: { toggle: 'tab' }, role: 'tab' } + %span Add existing cluster - %p= s_('ClusterIntegration|Create a new Kubernetes cluster on Google Kubernetes Engine right from GitLab') - = link_to s_('ClusterIntegration|Create on Google Kubernetes Engine'), gcp_new_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20' - %p= s_('ClusterIntegration|Enter the details for an existing Kubernetes cluster') - = link_to s_('ClusterIntegration|Add an existing Kubernetes cluster'), user_new_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20' + .tab-content.gitlab-tab-content + .tab-pane{ id: 'create-gcp-cluster-pane', class: active_when(active_tab == 'gcp'), role: 'tabpanel' } + = render 'projects/clusters/gcp/header' + - if @valid_gcp_token + = render 'projects/clusters/gcp/form' + - elsif @authorize_url + .signin-with-google + = link_to(image_tag('auth_buttons/signin_with_google.png', width: '191px'), @authorize_url) + = _('or') + = link_to('create a new Google account', 'https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.cloud.google.com%2Ffreetrial%3Futm_campaign%3D2018_cpanel%26utm_source%3Dgitlab%26utm_medium%3Dreferral', target: '_blank', rel: 'noopener noreferrer') + - else + - link = link_to(s_('ClusterIntegration|properly configured'), help_page_path("integration/google"), target: '_blank', rel: 'noopener noreferrer') + = s_('Google authentication is not %{link_to_documentation}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_to_documentation: link } + + .tab-pane{ id: 'add-user-cluster-pane', class: active_when(active_tab == 'user'), role: 'tabpanel' } + = render 'projects/clusters/user/header' + = render 'projects/clusters/user/form' diff --git a/app/views/projects/clusters/user/_form.html.haml b/app/views/projects/clusters/user/_form.html.haml index db57da99ec7..5590ade893c 100644 --- a/app/views/projects/clusters/user/_form.html.haml +++ b/app/views/projects/clusters/user/_form.html.haml @@ -1,5 +1,5 @@ -= form_for @cluster, url: user_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field| - = form_errors(@cluster) += form_for @user_cluster, url: create_user_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field| + = form_errors(@user_cluster) .form-group = field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light' = field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name') @@ -7,7 +7,7 @@ = field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-light' = field.text_field :environment_scope, class: 'form-control', readonly: !has_multiple_clusters?(@project), placeholder: s_('ClusterIntegration|Environment scope') - = field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field| + = field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field| .form-group = platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-light' = platform_kubernetes_field.text_field :api_url, class: 'form-control', placeholder: s_('ClusterIntegration|API URL') diff --git a/app/views/projects/clusters/user/_header.html.haml b/app/views/projects/clusters/user/_header.html.haml index 37f6a788518..749177fa6c1 100644 --- a/app/views/projects/clusters/user/_header.html.haml +++ b/app/views/projects/clusters/user/_header.html.haml @@ -1,4 +1,4 @@ -%h4.prepend-top-20 +%h4 = s_('ClusterIntegration|Enter the details for your Kubernetes cluster') %p - link_to_help_page = link_to(s_('ClusterIntegration|documentation'), help_page_path('user/project/clusters/index', anchor: 'adding-an-existing-kubernetes-cluster'), target: '_blank', rel: 'noopener noreferrer') diff --git a/app/views/projects/clusters/user/new.html.haml b/app/views/projects/clusters/user/new.html.haml deleted file mode 100644 index 7fb75cd9cc7..00000000000 --- a/app/views/projects/clusters/user/new.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- breadcrumb_title 'Kubernetes' -- page_title _("New Kubernetes cluster") - -.row.prepend-top-default - .col-sm-4 - = render 'projects/clusters/sidebar' - .col-sm-8 - = render 'projects/clusters/dropdown', dropdown_text: s_('ClusterIntegration|Add an existing Kubernetes cluster') - = render 'header' - .prepend-top-20 - = render 'form' diff --git a/changelogs/unreleased/43446-new-cluster-page-tabs.yml b/changelogs/unreleased/43446-new-cluster-page-tabs.yml new file mode 100644 index 00000000000..e8c73257b16 --- /dev/null +++ b/changelogs/unreleased/43446-new-cluster-page-tabs.yml @@ -0,0 +1,5 @@ +--- +title: Create new or add existing Kubernetes cluster from a single page +merge_request: 18963 +author: +type: changed diff --git a/config/routes/project.rb b/config/routes/project.rb index 6dfbd7ecd1f..082a1166c41 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -206,14 +206,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do resources :clusters, except: [:edit, :create] do collection do - scope :providers do - get '/user/new', to: 'clusters/user#new' - post '/user', to: 'clusters/user#create' - - get '/gcp/new', to: 'clusters/gcp#new' - get '/gcp/login', to: 'clusters/gcp#login' - post '/gcp', to: 'clusters/gcp#create' - end + post :create_gcp + post :create_user end member do diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md index 58a483bb3b2..67f8ec4f1d8 100644 --- a/doc/user/project/clusters/index.md +++ b/doc/user/project/clusters/index.md @@ -23,39 +23,43 @@ You need Maintainer [permissions] and above to access the Kubernetes page. Before proceeding, make sure the following requirements are met: -- The [Google authentication integration](../../../integration/google.md) must +* The [Google authentication integration](../../../integration/google.md) must be enabled in GitLab at the instance level. If that's not the case, ask your GitLab administrator to enable it. -- Your associated Google account must have the right privileges to manage +* Your associated Google account must have the right privileges to manage clusters on GKE. That would mean that a [billing account](https://cloud.google.com/billing/docs/how-to/manage-billing-account) must be set up and that you have to have permissions to access it. + - You must have Maintainer [permissions] in order to be able to access the **Kubernetes** page. -- You must have [Cloud Billing API](https://cloud.google.com/billing/) enabled -- You must have [Resource Manager + +* You must have [Cloud Billing API](https://cloud.google.com/billing/) enabled +* You must have [Resource Manager API](https://cloud.google.com/resource-manager/) If all of the above requirements are met, you can proceed to create and add a new Kubernetes cluster that will be hosted on GKE to your project: -1. Navigate to your project's **Operations > Kubernetes** page. -1. Click on **Add Kubernetes cluster**. -1. Click on **Create with Google Kubernetes Engine**. -1. Connect your Google account if you haven't done already by clicking the - **Sign in with Google** button. -1. Fill in the requested values: - - **Kubernetes cluster name** - The name you wish to give the cluster. - - **Environment scope** - The [associated environment](#setting-the-environment-scope) to this cluster. - - **Google Cloud Platform project** - The project you created in your GCP - console that will host the Kubernetes cluster. This must **not** be confused - with the project ID. Learn more about [Google Cloud Platform projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects). - - **Zone** - The [zone](https://cloud.google.com/compute/docs/regions-zones/) - under which the cluster will be created. - - **Number of nodes** - The number of nodes you wish the cluster to have. - - **Machine type** - The [machine type](https://cloud.google.com/compute/docs/machine-types) - of the Virtual Machine instance that the cluster will be based on. -1. Finally, click the **Create Kubernetes cluster** button. +1. Navigate to your project's **Operations > Kubernetes** page. +1. Click on **Add Kubernetes cluster**. +1. Click on **Create with Google Kubernetes Engine**. +1. Connect your Google account if you haven't done already by clicking the + **Sign in with Google** button. +1. Fill in the requested values: + +* **Kubernetes cluster name** - The name you wish to give the cluster. +* **Environment scope** - The [associated environment](#setting-the-environment-scope) to this cluster. +* **Google Cloud Platform project** - The project you created in your GCP + console that will host the Kubernetes cluster. This must **not** be confused + with the project ID. Learn more about [Google Cloud Platform projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects). +* **Zone** - The [zone](https://cloud.google.com/compute/docs/regions-zones/) + under which the cluster will be created. +* **Number of nodes** - The number of nodes you wish the cluster to have. +* **Machine type** - The [machine type](https://cloud.google.com/compute/docs/machine-types) + of the Virtual Machine instance that the cluster will be based on. + +1. Finally, click the **Create Kubernetes cluster** button. After a few moments, your cluster should be created. If something goes wrong, you will be notified. @@ -70,11 +74,11 @@ You need Maintainer [permissions] and above to access the Kubernetes page. To add an existing Kubernetes cluster to your project: -1. Navigate to your project's **Operations > Kubernetes** page. -1. Click on **Add Kubernetes cluster**. -1. Click on **Add an existing Kubernetes cluster** and fill in the details: - - **Kubernetes cluster name** (required) - The name you wish to give the cluster. - - **Environment scope** (required)- The +1. Navigate to your project's **Operations > Kubernetes** page. +1. Click on **Add Kubernetes cluster**. +1. Click on **Add an existing Kubernetes cluster** and fill in the details: + * **Kubernetes cluster name** (required) - The name you wish to give the cluster. + * **Environment scope** (required)- The [associated environment](#setting-the-environment-scope) to this cluster. - **API URL** (required) - It's the URL that GitLab uses to access the Kubernetes API. Kubernetes @@ -92,16 +96,16 @@ To add an existing Kubernetes cluster to your project: [Kubernetes dashboard](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/#config) (under **Config > Secrets**). - **Project namespace** (optional) - The following apply: - - By default you don't have to fill it in; by leaving it blank, GitLab will + * By default you don't have to fill it in; by leaving it blank, GitLab will create one for you. - - Each project should have a unique namespace. - - The project namespace is not necessarily the namespace of the secret, if + * Each project should have a unique namespace. + * The project namespace is not necessarily the namespace of the secret, if you're using a secret with broader permissions, like the secret from `default`. - - You should **not** use `default` as the project namespace. - - If you or someone created a secret specifically for the project, usually + * You should **not** use `default` as the project namespace. + * If you or someone created a secret specifically for the project, usually with limited permissions, the secret's namespace and project namespace may be the same. -1. Finally, click the **Create Kubernetes cluster** button. +1. Finally, click the **Add Kubernetes cluster** button. After a few moments, your cluster should be created. If something goes wrong, you will be notified. @@ -150,6 +154,15 @@ GitLab provides a one-click install for various applications which will be added directly to your configured cluster. Those applications are needed for [Review Apps](../../../ci/review_apps/index.md) and [deployments](../../../ci/environments.md). +<<<<<<< HEAD +| Application | GitLab version | Description | +| --------------------------------------------------------------------------- | :------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Helm Tiller](https://docs.helm.sh/) | 10.2+ | Helm is a package manager for Kubernetes and is required to install all the other applications. It will be automatically installed as a dependency when you try to install a different app. It is installed in its own pod inside the cluster which can run the `helm` CLI in a safe environment. | +| [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | 10.2+ | Ingress can provide load balancing, SSL termination, and name-based virtual hosting. It acts as a web proxy for your applications and is useful if you want to use [Auto DevOps] or deploy your own web apps. | +| [Prometheus](https://prometheus.io/docs/introduction/overview/) | 10.4+ | Prometheus is an open-source monitoring and alerting system useful to supervise your deployed applications | +| [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. When installing the GitLab Runner via the applications, it will run in **privileged mode** by default. Make sure you read the [security implications](#security-implications) before doing so. | +| [JupyterHub](http://jupyter.org/) | 11.0+ | The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text. | +======= | Application | GitLab version | Description | | ----------- | :------------: | ----------- | | [Helm Tiller](https://docs.helm.sh/) | 10.2+ | Helm is a package manager for Kubernetes and is required to install all the other applications. It will be automatically installed as a dependency when you try to install a different app. It is installed in its own pod inside the cluster which can run the `helm` CLI in a safe environment. | @@ -158,6 +171,8 @@ added directly to your configured cluster. Those applications are needed for | [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. When installing the GitLab Runner via the applications, it will run in **privileged mode** by default. Make sure you read the [security implications](#security-implications) before doing so. | | [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. | +> > > > > > > origin/master + ## Getting the external IP address NOTE: **Note:** @@ -202,6 +217,7 @@ kubectl get svc --all-namespaces -o jsonpath='{range.items[?(@.status.loadBalanc ``` > **Note**: Some Kubernetes clusters return a hostname instead, like [Amazon EKS](https://aws.amazon.com/eks/). For these platforms, run: +> > ```bash > kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"`. > ``` @@ -250,11 +266,11 @@ Also, jobs that don't have an environment keyword set will not be able to access For example, let's say the following Kubernetes clusters exist in a project: -| Cluster | Environment scope | -| ---------- | ------------------- | -| Development| `*` | -| Staging | `staging/*` | -| Production | `production/*` | +| Cluster | Environment scope | +| ----------- | ----------------- | +| Development | `*` | +| Staging | `staging/*` | +| Production | `production/*` | And the following environments are set in [`.gitlab-ci.yml`](../../../ci/yaml/README.md): @@ -284,9 +300,9 @@ deploy to production: The result will then be: -- The development cluster will be used for the "test" job. -- The staging cluster will be used for the "deploy to staging" job. -- The production cluster will be used for the "deploy to production" job. +* The development cluster will be used for the "test" job. +* The staging cluster will be used for the "deploy to staging" job. +* The production cluster will be used for the "deploy to production" job. ## Multiple Kubernetes clusters @@ -306,22 +322,22 @@ The Kubernetes cluster integration exposes the following [deployment variables](../../../ci/variables/README.md#deployment-variables) in the GitLab CI/CD build environment. -| Variable | Description | -| -------- | ----------- | -| `KUBE_URL` | Equal to the API URL. | -| `KUBE_TOKEN` | The Kubernetes token. | -| `KUBE_NAMESPACE` | The Kubernetes namespace is auto-generated if not specified. The default value is `<project_name>-<project_id>`. You can overwrite it to use different one if needed, otherwise the `KUBE_NAMESPACE` variable will receive the default value. | -| `KUBE_CA_PEM_FILE` | Only present if a custom CA bundle was specified. Path to a file containing PEM data. | -| `KUBE_CA_PEM` | (**deprecated**) Only if a custom CA bundle was specified. Raw PEM data. | -| `KUBECONFIG` | Path to a file containing `kubeconfig` for this deployment. CA bundle would be embedded if specified. | +| Variable | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `KUBE_URL` | Equal to the API URL. | +| `KUBE_TOKEN` | The Kubernetes token. | +| `KUBE_NAMESPACE` | The Kubernetes namespace is auto-generated if not specified. The default value is `<project_name>-<project_id>`. You can overwrite it to use different one if needed, otherwise the `KUBE_NAMESPACE` variable will receive the default value. | +| `KUBE_CA_PEM_FILE` | Only present if a custom CA bundle was specified. Path to a file containing PEM data. | +| `KUBE_CA_PEM` | (**deprecated**) Only if a custom CA bundle was specified. Raw PEM data. | +| `KUBECONFIG` | Path to a file containing `kubeconfig` for this deployment. CA bundle would be embedded if specified. | ## Enabling or disabling the Kubernetes cluster integration After you have successfully added your cluster information, you can enable the Kubernetes cluster integration: -1. Click the "Enabled/Disabled" switch -1. Hit **Save** for the changes to take effect +1. Click the "Enabled/Disabled" switch +1. Hit **Save** for the changes to take effect You can now start using your Kubernetes cluster for your deployments. @@ -400,8 +416,8 @@ the deployment variables above, ensuring any pods you create are labelled with ## Read more -- [Connecting and deploying to an Amazon EKS cluster](eks_and_gitlab/index.md) +* [Connecting and deploying to an Amazon EKS cluster](eks_and_gitlab/index.md) [permissions]: ../../permissions.md [ee]: https://about.gitlab.com/products/ -[Auto DevOps]: ../../../topics/autodevops/index.md +[auto devops]: ../../../topics/autodevops/index.md diff --git a/qa/qa/page/project/operations/kubernetes/add.rb b/qa/qa/page/project/operations/kubernetes/add.rb index 9b3c482fa6c..11ebe10fb18 100644 --- a/qa/qa/page/project/operations/kubernetes/add.rb +++ b/qa/qa/page/project/operations/kubernetes/add.rb @@ -5,11 +5,11 @@ module QA module Kubernetes class Add < Page::Base view 'app/views/projects/clusters/new.html.haml' do - element :add_kubernetes_cluster_button, "link_to s_('ClusterIntegration|Add an existing Kubernetes cluster')" + element :add_existing_cluster_button, "Add existing cluster" end def add_existing_cluster - click_on 'Add an existing Kubernetes cluster' + click_on 'Add existing cluster' end end end diff --git a/spec/controllers/projects/clusters/gcp_controller_spec.rb b/spec/controllers/projects/clusters/gcp_controller_spec.rb deleted file mode 100644 index 271ba37aed4..00000000000 --- a/spec/controllers/projects/clusters/gcp_controller_spec.rb +++ /dev/null @@ -1,182 +0,0 @@ -require 'spec_helper' - -describe Projects::Clusters::GcpController do - include AccessMatchersForController - include GoogleApi::CloudPlatformHelpers - - set(:project) { create(:project) } - - describe 'GET login' do - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when omniauth has been configured' do - let(:key) { 'secret-key' } - let(:session_key_for_redirect_uri) do - GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(key) - end - - before do - allow(SecureRandom).to receive(:hex).and_return(key) - end - - it 'has authorize_url' do - go - - expect(assigns(:authorize_url)).to include(key) - expect(session[session_key_for_redirect_uri]).to eq(gcp_new_project_clusters_path(project)) - end - end - - context 'when omniauth has not configured' do - before do - stub_omniauth_setting(providers: []) - end - - it 'does not have authorize_url' do - go - - expect(assigns(:authorize_url)).to be_nil - end - end - end - - describe 'security' do - it { expect { go }.to be_allowed_for(:admin) } - it { expect { go }.to be_allowed_for(:owner).of(project) } - it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } - it { expect { go }.to be_denied_for(:reporter).of(project) } - it { expect { go }.to be_denied_for(:guest).of(project) } - it { expect { go }.to be_denied_for(:user) } - it { expect { go }.to be_denied_for(:external) } - end - - def go - get :login, namespace_id: project.namespace, project_id: project - end - end - - describe 'GET new' do - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when access token is valid' do - before do - stub_google_api_validate_token - end - - it 'has new object' do - go - - expect(assigns(:cluster)).to be_an_instance_of(Clusters::Cluster) - end - end - - context 'when access token is expired' do - before do - stub_google_api_expired_token - end - - it { expect(go).to redirect_to(gcp_login_project_clusters_path(project)) } - end - - context 'when access token is not stored in session' do - it { expect(go).to redirect_to(gcp_login_project_clusters_path(project)) } - end - end - - describe 'security' do - it { expect { go }.to be_allowed_for(:admin) } - it { expect { go }.to be_allowed_for(:owner).of(project) } - it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } - it { expect { go }.to be_denied_for(:reporter).of(project) } - it { expect { go }.to be_denied_for(:guest).of(project) } - it { expect { go }.to be_denied_for(:user) } - it { expect { go }.to be_denied_for(:external) } - end - - def go - get :new, namespace_id: project.namespace, project_id: project - end - end - - describe 'POST create' do - let(:params) do - { - cluster: { - name: 'new-cluster', - provider_gcp_attributes: { - gcp_project_id: '111' - } - } - } - end - - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when access token is valid' do - before do - stub_google_api_validate_token - end - - it 'creates a new cluster' do - expect(ClusterProvisionWorker).to receive(:perform_async) - expect { go }.to change { Clusters::Cluster.count } - .and change { Clusters::Providers::Gcp.count } - expect(response).to redirect_to(project_cluster_path(project, project.clusters.first)) - expect(project.clusters.first).to be_gcp - expect(project.clusters.first).to be_kubernetes - end - end - - context 'when access token is expired' do - before do - stub_google_api_expired_token - end - - it 'redirects to login page' do - expect(go).to redirect_to(gcp_login_project_clusters_path(project)) - end - end - - context 'when access token is not stored in session' do - it 'redirects to login page' do - expect(go).to redirect_to(gcp_login_project_clusters_path(project)) - end - end - end - - describe 'security' do - it { expect { go }.to be_allowed_for(:admin) } - it { expect { go }.to be_allowed_for(:owner).of(project) } - it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } - it { expect { go }.to be_denied_for(:reporter).of(project) } - it { expect { go }.to be_denied_for(:guest).of(project) } - it { expect { go }.to be_denied_for(:user) } - it { expect { go }.to be_denied_for(:external) } - end - - def go - post :create, params.merge(namespace_id: project.namespace, project_id: project) - end - end -end diff --git a/spec/controllers/projects/clusters/user_controller_spec.rb b/spec/controllers/projects/clusters/user_controller_spec.rb deleted file mode 100644 index 913976d187f..00000000000 --- a/spec/controllers/projects/clusters/user_controller_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'spec_helper' - -describe Projects::Clusters::UserController do - include AccessMatchersForController - - set(:project) { create(:project) } - - describe 'GET new' do - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - end - - it 'has new object' do - go - - expect(assigns(:cluster)).to be_an_instance_of(Clusters::Cluster) - end - end - - describe 'security' do - it { expect { go }.to be_allowed_for(:admin) } - it { expect { go }.to be_allowed_for(:owner).of(project) } - it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } - it { expect { go }.to be_denied_for(:reporter).of(project) } - it { expect { go }.to be_denied_for(:guest).of(project) } - it { expect { go }.to be_denied_for(:user) } - it { expect { go }.to be_denied_for(:external) } - end - - def go - get :new, namespace_id: project.namespace, project_id: project - end - end - - describe 'POST create' do - let(:params) do - { - cluster: { - name: 'new-cluster', - platform_kubernetes_attributes: { - api_url: 'http://my-url', - token: 'test', - namespace: 'aaa' - } - } - } - end - - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_master(user) - sign_in(user) - end - - context 'when creates a cluster' do - it 'creates a new cluster' do - expect(ClusterProvisionWorker).to receive(:perform_async) - expect { go }.to change { Clusters::Cluster.count } - .and change { Clusters::Platforms::Kubernetes.count } - expect(response).to redirect_to(project_cluster_path(project, project.clusters.first)) - expect(project.clusters.first).to be_user - expect(project.clusters.first).to be_kubernetes - end - end - end - - describe 'security' do - it { expect { go }.to be_allowed_for(:admin) } - it { expect { go }.to be_allowed_for(:owner).of(project) } - it { expect { go }.to be_allowed_for(:master).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } - it { expect { go }.to be_denied_for(:reporter).of(project) } - it { expect { go }.to be_denied_for(:guest).of(project) } - it { expect { go }.to be_denied_for(:user) } - it { expect { go }.to be_denied_for(:external) } - end - - def go - post :create, params.merge(namespace_id: project.namespace, project_id: project) - end - end -end diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index 380e50c8cac..e47ccdc9aea 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe Projects::ClustersController do include AccessMatchersForController + include GoogleApi::CloudPlatformHelpers set(:project) { create(:project) } @@ -73,6 +74,231 @@ describe Projects::ClustersController do end end + describe 'GET new' do + describe 'functionality for new cluster' do + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + context 'when omniauth has been configured' do + let(:key) { 'secret-key' } + let(:session_key_for_redirect_uri) do + GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(key) + end + + before do + allow(SecureRandom).to receive(:hex).and_return(key) + end + + it 'has authorize_url' do + go + + expect(assigns(:authorize_url)).to include(key) + expect(session[session_key_for_redirect_uri]).to eq(new_project_cluster_path(project)) + end + end + + context 'when omniauth has not configured' do + before do + stub_omniauth_setting(providers: []) + end + + it 'does not have authorize_url' do + go + + expect(assigns(:authorize_url)).to be_nil + end + end + + context 'when access token is valid' do + before do + stub_google_api_validate_token + end + + it 'has new object' do + go + + expect(assigns(:gcp_cluster)).to be_an_instance_of(Clusters::Cluster) + end + end + + context 'when access token is expired' do + before do + stub_google_api_expired_token + end + + it { expect(@valid_gcp_token).to be_falsey } + end + + context 'when access token is not stored in session' do + it { expect(@valid_gcp_token).to be_falsey } + end + end + + describe 'functionality for existing cluster' do + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + it 'has new object' do + go + + expect(assigns(:user_cluster)).to be_an_instance_of(Clusters::Cluster) + end + end + + describe 'security' do + it { expect { go }.to be_allowed_for(:admin) } + it { expect { go }.to be_allowed_for(:owner).of(project) } + it { expect { go }.to be_allowed_for(:master).of(project) } + it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_denied_for(:reporter).of(project) } + it { expect { go }.to be_denied_for(:guest).of(project) } + it { expect { go }.to be_denied_for(:user) } + it { expect { go }.to be_denied_for(:external) } + end + + def go + get :new, namespace_id: project.namespace, project_id: project + end + end + + describe 'POST create for new cluster' do + let(:params) do + { + cluster: { + name: 'new-cluster', + provider_gcp_attributes: { + gcp_project_id: 'gcp-project-12345' + } + } + } + end + + describe 'functionality' do + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + context 'when access token is valid' do + before do + stub_google_api_validate_token + end + + it 'creates a new cluster' do + expect(ClusterProvisionWorker).to receive(:perform_async) + expect { go }.to change { Clusters::Cluster.count } + .and change { Clusters::Providers::Gcp.count } + expect(response).to redirect_to(project_cluster_path(project, project.clusters.first)) + expect(project.clusters.first).to be_gcp + expect(project.clusters.first).to be_kubernetes + end + end + + context 'when access token is expired' do + before do + stub_google_api_expired_token + end + + it { expect(@valid_gcp_token).to be_falsey } + end + + context 'when access token is not stored in session' do + it { expect(@valid_gcp_token).to be_falsey } + end + end + + describe 'security' do + before do + allow_any_instance_of(described_class) + .to receive(:token_in_session).and_return('token') + allow_any_instance_of(described_class) + .to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s) + allow_any_instance_of(GoogleApi::CloudPlatform::Client) + .to receive(:projects_zones_clusters_create) do + OpenStruct.new( + self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123', + status: 'RUNNING' + ) + end + + allow(WaitForClusterCreationWorker).to receive(:perform_in).and_return(nil) + end + + it { expect { go }.to be_allowed_for(:admin) } + it { expect { go }.to be_allowed_for(:owner).of(project) } + it { expect { go }.to be_allowed_for(:master).of(project) } + it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_denied_for(:reporter).of(project) } + it { expect { go }.to be_denied_for(:guest).of(project) } + it { expect { go }.to be_denied_for(:user) } + it { expect { go }.to be_denied_for(:external) } + end + + def go + post :create_gcp, params.merge(namespace_id: project.namespace, project_id: project) + end + end + + describe 'POST create for existing cluster' do + let(:params) do + { + cluster: { + name: 'new-cluster', + platform_kubernetes_attributes: { + api_url: 'http://my-url', + token: 'test', + namespace: 'aaa' + } + } + } + end + + describe 'functionality' do + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + context 'when creates a cluster' do + it 'creates a new cluster' do + expect(ClusterProvisionWorker).to receive(:perform_async) + expect { go }.to change { Clusters::Cluster.count } + .and change { Clusters::Platforms::Kubernetes.count } + expect(response).to redirect_to(project_cluster_path(project, project.clusters.first)) + expect(project.clusters.first).to be_user + expect(project.clusters.first).to be_kubernetes + end + end + end + + describe 'security' do + it { expect { go }.to be_allowed_for(:admin) } + it { expect { go }.to be_allowed_for(:owner).of(project) } + it { expect { go }.to be_allowed_for(:master).of(project) } + it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_denied_for(:reporter).of(project) } + it { expect { go }.to be_denied_for(:guest).of(project) } + it { expect { go }.to be_denied_for(:user) } + it { expect { go }.to be_denied_for(:external) } + end + + def go + post :create_user, params.merge(namespace_id: project.namespace, project_id: project) + end + end + describe 'GET status' do let(:cluster) { create(:cluster, :providing_by_gcp, projects: [project]) } diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index c85b82b2090..0ebe3459a65 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -16,9 +16,9 @@ feature 'Gcp Cluster', :js do let(:project_id) { 'test-project-1234' } before do - allow_any_instance_of(Projects::Clusters::GcpController) + allow_any_instance_of(Projects::ClustersController) .to receive(:token_in_session).and_return('token') - allow_any_instance_of(Projects::Clusters::GcpController) + allow_any_instance_of(Projects::ClustersController) .to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s) end @@ -27,7 +27,7 @@ feature 'Gcp Cluster', :js do visit project_clusters_path(project) click_link 'Add Kubernetes cluster' - click_link 'Create on Google Kubernetes Engine' + click_link 'Create new Cluster on GKE' end context 'when user filled form with valid parameters' do @@ -148,7 +148,7 @@ feature 'Gcp Cluster', :js do visit project_clusters_path(project) click_link 'Add Kubernetes cluster' - click_link 'Create on Google Kubernetes Engine' + click_link 'Create new Cluster on GKE' end it 'user sees a login page' do @@ -174,7 +174,7 @@ feature 'Gcp Cluster', :js do it 'user sees offer on cluster GCP login page' do click_link 'Add Kubernetes cluster' - click_link 'Create on Google Kubernetes Engine' + click_link 'Create new Cluster on GKE' expect(page).to have_css('.gcp-signup-offer') end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 698b64a659c..766ea58cc17 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -17,7 +17,7 @@ feature 'User Cluster', :js do visit project_clusters_path(project) click_link 'Add Kubernetes cluster' - click_link 'Add an existing Kubernetes cluster' + click_link 'Add existing cluster' end context 'when user filled form with valid parameters' do diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb index a251a2f4e52..64241102c8b 100644 --- a/spec/features/projects/clusters_spec.rb +++ b/spec/features/projects/clusters_spec.rb @@ -83,7 +83,7 @@ feature 'Clusters', :js do visit project_clusters_path(project) click_link 'Add Kubernetes cluster' - click_link 'Create on Google Kubernetes Engine' + click_link 'Create new Cluster on GKE' end it 'user sees a login page' do |