diff options
author | Mayra Cabrera <mcabrera@gitlab.com> | 2019-01-23 16:01:56 -0600 |
---|---|---|
committer | Mayra Cabrera <mcabrera@gitlab.com> | 2019-01-23 19:35:10 -0600 |
commit | 9b2851cf71310b812f6cbdcff706420d13624e8b (patch) | |
tree | 54498145c2c2272349a41b3cc56290b8147b45cf | |
parent | 8d90f81731ccc10f3239fecfd232f84bdae23665 (diff) | |
download | gitlab-ce-56750-fix-validation-error-appearing-twice-on-cluster-page.tar.gz |
Split cluster and kubernetes forms56750-fix-validation-error-appearing-twice-on-cluster-page
- Add a kubernetes partial form that will enable or disable the fields
based if the cluster is managed or not
- Add a controller for Clusters::Platforms::Kubernetes
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/56750
16 files changed, 205 insertions, 117 deletions
diff --git a/app/assets/javascripts/pages/groups/clusters/platforms/kubernetes/edit/index.js b/app/assets/javascripts/pages/groups/clusters/platforms/kubernetes/edit/index.js new file mode 100644 index 00000000000..8001d2dd1da --- /dev/null +++ b/app/assets/javascripts/pages/groups/clusters/platforms/kubernetes/edit/index.js @@ -0,0 +1,5 @@ +import ClustersBundle from '~/clusters/clusters_bundle'; + +document.addEventListener('DOMContentLoaded', () => { + new ClustersBundle(); // eslint-disable-line no-new +}); diff --git a/app/assets/javascripts/pages/projects/clusters/platforms/kubernetes/edit/index.js b/app/assets/javascripts/pages/projects/clusters/platforms/kubernetes/edit/index.js new file mode 100644 index 00000000000..8001d2dd1da --- /dev/null +++ b/app/assets/javascripts/pages/projects/clusters/platforms/kubernetes/edit/index.js @@ -0,0 +1,5 @@ +import ClustersBundle from '~/clusters/clusters_bundle'; + +document.addEventListener('DOMContentLoaded', () => { + new ClustersBundle(); // eslint-disable-line no-new +}); diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index b9717b97640..bafdd81fc91 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -123,27 +123,10 @@ class Clusters::ClustersController < Clusters::BaseController private def update_params - if cluster.managed? - params.require(:cluster).permit( - :enabled, - :environment_scope, - platform_kubernetes_attributes: [ - :namespace - ] - ) - else - params.require(:cluster).permit( - :enabled, - :name, - :environment_scope, - platform_kubernetes_attributes: [ - :api_url, - :token, - :ca_cert, - :namespace - ] - ) - end + params.require(:cluster).permit( + :enabled, + :environment_scope, + ) end def create_gcp_cluster_params diff --git a/app/controllers/clusters/platforms/kubernetes_controller.rb b/app/controllers/clusters/platforms/kubernetes_controller.rb new file mode 100644 index 00000000000..894e4e799f5 --- /dev/null +++ b/app/controllers/clusters/platforms/kubernetes_controller.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +class Clusters::Platforms::KubernetesController < Clusters::BaseController + include RoutableActions + + before_action :cluster + before_action :kubernetes, only: [:update] + before_action :authorize_update_cluster!, only: [:update] + + + def update + kubernetes.update(update_params) + + if kubernetes.valid? + respond_to do |format| + format.json do + head :no_content + end + format.html do + flash[:notice] = _('Kubernetes cluster was successfully updated.') + redirect_to cluster.show_path + end + end + else + respond_to do |format| + format.html { render 'clusters/clusters/show' } + end + end + end + + private + + def cluster + @cluster ||= clusterable.clusters.find(params[:id]) + .present(current_user: current_user) + end + + def kubernetes + @kubernetes ||= cluster.platform_kubernetes + end + + def update_params + if cluster.managed? + params.require(:platform_kubernetes).permit(:namespace) + else + params.require(:platform_kubernetes).permit( + :api_url, + :token, + :ca_cert, + :namespace, + cluster_attributes: [ + :name + ] + ) + end + end + + def authorize_update_cluster! + access_denied! unless can?(current_user, :update_cluster, cluster) + end + + def clusterable + raise NotImplementedError + end +end diff --git a/app/controllers/groups/clusters/platforms/kubernetes_controller.rb b/app/controllers/groups/clusters/platforms/kubernetes_controller.rb new file mode 100644 index 00000000000..7326349b876 --- /dev/null +++ b/app/controllers/groups/clusters/platforms/kubernetes_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class Groups::Clusters::Platforms::KubernetesController < Clusters::Platforms::KubernetesController + include ControllerWithCrossProjectAccessCheck + + prepend_before_action :group + requires_cross_project_access + + layout 'group' + + private + + def clusterable + @clusterable ||= ClusterablePresenter.fabricate(group, current_user: current_user) + end + + def group + @group ||= find_routable!(Group, params[:group_id] || params[:id]) + end +end diff --git a/app/controllers/projects/clusters/platforms/kubernetes_controller.rb b/app/controllers/projects/clusters/platforms/kubernetes_controller.rb new file mode 100644 index 00000000000..d3443b7f3ad --- /dev/null +++ b/app/controllers/projects/clusters/platforms/kubernetes_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class Projects::Clusters::Platforms::KubernetesController < Clusters::Platforms::KubernetesController + include ProjectUnauthorized + + prepend_before_action :project + + layout 'project' + + private + + def clusterable + @clusterable ||= ClusterablePresenter.fabricate(project, current_user: current_user) + end + + def project + @project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), not_found_or_authorized_proc: project_unauthorized_proc) + end +end diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index 1cc170c8c4d..dca95791727 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -59,6 +59,8 @@ module Clusters alias_method :active?, :enabled? + accepts_nested_attributes_for :cluster, update_only: true + enum_with_nil authorization_type: { unknown_authorization: nil, rbac: 1, diff --git a/app/presenters/clusterable_presenter.rb b/app/presenters/clusterable_presenter.rb index d94d9118eee..58b5969b5c5 100644 --- a/app/presenters/clusterable_presenter.rb +++ b/app/presenters/clusterable_presenter.rb @@ -59,4 +59,8 @@ class ClusterablePresenter < Gitlab::View::Presenter::Delegated def learn_more_link raise NotImplementedError end + + def platform_kubernetes_path(cluster, platform_kubernetes) + raise NotImplementedError + end end diff --git a/app/presenters/group_clusterable_presenter.rb b/app/presenters/group_clusterable_presenter.rb index ef6bbc0d109..fdff7a4a00d 100644 --- a/app/presenters/group_clusterable_presenter.rb +++ b/app/presenters/group_clusterable_presenter.rb @@ -33,4 +33,9 @@ class GroupClusterablePresenter < ClusterablePresenter def learn_more_link link_to(s_('ClusterIntegration|Learn more about group Kubernetes clusters'), help_page_path('user/group/clusters/index'), target: '_blank', rel: 'noopener noreferrer') end + + override :platform_kubernetes_path + def platform_kubernetes_path(cluster, platform_kubernetes) + group_cluster_platform_kubernete_path(clusterable, cluster, platform_kubernetes) + end end diff --git a/app/presenters/project_clusterable_presenter.rb b/app/presenters/project_clusterable_presenter.rb index 63e69b91b11..627bdd79c50 100644 --- a/app/presenters/project_clusterable_presenter.rb +++ b/app/presenters/project_clusterable_presenter.rb @@ -28,4 +28,14 @@ class ProjectClusterablePresenter < ClusterablePresenter def learn_more_link link_to(s_('ClusterIntegration|Learn more about Kubernetes'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') end + + override :platform_kubernetes_path + def platform_kubernetes_path(cluster, platform_kubernetes) + update_platform_kubernetes_namespace_project_cluster_path( + id: cluster, + kubernetes_id: platform_kubernetes, + namespace_id: clusterable.namespace.becomes(Namespace), + project_id: clusterable + ) + end end diff --git a/app/views/clusters/clusters/_integration_form.html.haml b/app/views/clusters/clusters/_form.html.haml index 4c47e11927e..4c47e11927e 100644 --- a/app/views/clusters/clusters/_integration_form.html.haml +++ b/app/views/clusters/clusters/_form.html.haml diff --git a/app/views/clusters/clusters/gcp/_show.html.haml b/app/views/clusters/clusters/gcp/_show.html.haml deleted file mode 100644 index e9f05eaf453..00000000000 --- a/app/views/clusters/clusters/gcp/_show.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -.form-group - %label.append-bottom-10{ for: 'cluster-name' } - = s_('ClusterIntegration|Kubernetes cluster name') - .input-group - %input.form-control.cluster-name.js-select-on-focus{ value: @cluster.name, readonly: true } - %span.input-group-append - = clipboard_button(text: @cluster.name, title: s_('ClusterIntegration|Copy Kubernetes cluster name'), class: 'input-group-text btn-default') - -= form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster do |field| - = form_errors(@cluster) - - = field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field| - .form-group - = platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL') - .input-group - = platform_kubernetes_field.text_field :api_url, class: 'form-control js-select-on-focus', placeholder: s_('ClusterIntegration|API URL'), readonly: true - %span.input-group-append - = clipboard_button(text: @cluster.platform_kubernetes.api_url, title: s_('ClusterIntegration|Copy API URL'), class: 'input-group-text btn-default') - - .form-group - = platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate') - .input-group - = platform_kubernetes_field.text_area :ca_cert, class: 'form-control js-select-on-focus', placeholder: s_('ClusterIntegration|Certificate Authority bundle (PEM format)'), readonly: true - %span.input-group-append.clipboard-addon - = clipboard_button(text: @cluster.platform_kubernetes.ca_cert, title: s_('ClusterIntegration|Copy CA Certificate'), class: 'input-group-text btn-blank') - - .form-group - = platform_kubernetes_field.label :token, s_('ClusterIntegration|Token') - .input-group - = platform_kubernetes_field.text_field :token, class: 'form-control js-cluster-token js-select-on-focus', type: 'password', placeholder: s_('ClusterIntegration|Token'), readonly: true - %span.input-group-append - %button.btn.btn-default.input-group-text.js-show-cluster-token{ type: 'button' } - = s_('ClusterIntegration|Show') - = clipboard_button(text: @cluster.platform_kubernetes.token, title: s_('ClusterIntegration|Copy Token'), class: 'btn-default') - - - if @cluster.allow_user_defined_namespace? - .form-group - = platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)') - = platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: s_('ClusterIntegration|Project namespace') - - .form-group - .form-check - = platform_kubernetes_field.check_box :authorization_type, { class: 'form-check-input', disabled: true }, 'rbac', 'abac' - = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold' - .form-text.text-muted - = s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).') - = s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.') - - .form-group - = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success' diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 89a2dfdd69f..b13a2a7ecc1 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -30,8 +30,8 @@ %section#cluster-integration %h4= @cluster.name - = render 'banner' - = render 'integration_form' + = render 'clusters/clusters/banner' + = render 'clusters/clusters/form' .cluster-applications-table#js-cluster-applications @@ -42,10 +42,8 @@ = expanded ? 'Collapse' : 'Expand' %p= s_('ClusterIntegration|See and edit the details for your Kubernetes cluster') .settings-content - - if @cluster.managed? - = render 'clusters/clusters/gcp/show' - - else - = render 'clusters/clusters/user/show' + = render 'clusters/platforms/kubernetes/form', cluster: @cluster, platform_kubernetes: @cluster.platform_kubernetes, update_cluster_url_path: clusterable.cluster_path(@cluster) + %section.settings.no-animate#js-cluster-advanced-settings{ class: ('expanded' if expanded) } .settings-header @@ -54,4 +52,4 @@ = expanded ? 'Collapse' : 'Expand' %p= s_("ClusterIntegration|Advanced options on this Kubernetes cluster's integration") .settings-content - = render 'advanced_settings' + = render 'clusters/clusters/advanced_settings' diff --git a/app/views/clusters/clusters/user/_show.html.haml b/app/views/clusters/clusters/user/_show.html.haml deleted file mode 100644 index cac8e72edd3..00000000000 --- a/app/views/clusters/clusters/user/_show.html.haml +++ /dev/null @@ -1,39 +0,0 @@ -= form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster do |field| - = form_errors(@cluster) - .form-group - = field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-bold' - = field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name') - - = field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field| - .form-group - = platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-bold' - = platform_kubernetes_field.text_field :api_url, class: 'form-control', placeholder: s_('ClusterIntegration|API URL') - - .form-group - = platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate'), class: 'label-bold' - = platform_kubernetes_field.text_area :ca_cert, class: 'form-control', placeholder: s_('ClusterIntegration|Certificate Authority bundle (PEM format)') - - .form-group - = platform_kubernetes_field.label :token, s_('ClusterIntegration|Token'), class: 'label-bold' - .input-group - = platform_kubernetes_field.text_field :token, class: 'form-control js-cluster-token', type: 'password', placeholder: s_('ClusterIntegration|Token'), autocomplete: 'off' - %span.input-group-append.clipboard-addon - .input-group-text - %button.js-show-cluster-token.btn-blank{ type: 'button' } - = s_('ClusterIntegration|Show') - - - if @cluster.allow_user_defined_namespace? - .form-group - = platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)'), class: 'label-bold' - = platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: s_('ClusterIntegration|Project namespace') - - .form-group - .form-check - = platform_kubernetes_field.check_box :authorization_type, { class: 'form-check-input', disabled: true }, 'rbac', 'abac' - = platform_kubernetes_field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold' - .form-text.text-muted - = s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).') - = s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.') - - .form-group - = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success' diff --git a/app/views/clusters/platforms/kubernetes/_form.html.haml b/app/views/clusters/platforms/kubernetes/_form.html.haml new file mode 100644 index 00000000000..184864760e2 --- /dev/null +++ b/app/views/clusters/platforms/kubernetes/_form.html.haml @@ -0,0 +1,58 @@ += form_for platform_kubernetes, url: clusterable.platform_kubernetes_path(cluster, platform_kubernetes), as: :platform_kubernetes do |field| + = form_errors(platform_kubernetes) + + .form-group + - if cluster.managed? + %label.append-bottom-10{ for: 'cluster-name' } + = s_('ClusterIntegration|Kubernetes cluster name') + .input-group + %input.form-control.cluster-name.js-select-on-focus{ value: cluster.name, readonly: true } + %span.input-group-append + = clipboard_button(text: cluster.name, title: s_('ClusterIntegration|Copy Kubernetes cluster name'), class: 'input-group-text btn-default') + - else + = field.fields_for :cluster, platform_kubernetes.cluster do |cluster_field| + = cluster_field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-bold' + .input-group + = cluster_field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name') + + .form-group + = field.label :api_url, s_('ClusterIntegration|API URL') + .input-group + = field.text_field :api_url, class: 'form-control js-select-on-focus', placeholder: s_('ClusterIntegration|API URL'), readonly: cluster.managed? + - if cluster.managed? + %span.input-group-append + = clipboard_button(text: platform_kubernetes.api_url, title: s_('ClusterIntegration|Copy API URL'), class: 'input-group-text btn-default') + + .form-group + = field.label :ca_cert, s_('ClusterIntegration|CA Certificate') + .input-group + = field.text_area :ca_cert, class: 'form-control js-select-on-focus', placeholder: s_('ClusterIntegration|Certificate Authority bundle (PEM format)'), readonly: cluster.managed? + - if cluster.managed? + %span.input-group-append.clipboard-addon + = clipboard_button(text: platform_kubernetes.ca_cert, title: s_('ClusterIntegration|Copy CA Certificate'), class: 'input-group-text btn-blank') + + .form-group + = field.label :token, s_('ClusterIntegration|Token') + .input-group + = field.text_field :token, class: 'form-control js-cluster-token js-select-on-focus', type: 'password', placeholder: s_('ClusterIntegration|Token'), readonly: cluster.managed? + %span.input-group-append + %button.btn.btn-default.input-group-text.js-show-cluster-token{ type: 'button' } + = s_('ClusterIntegration|Show') + - if cluster.managed? + = clipboard_button(text: platform_kubernetes.token, title: s_('ClusterIntegration|Copy Token'), class: 'btn-default') + + - if cluster.allow_user_defined_namespace? + .form-group + = field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)') + = field.text_field :namespace, class: 'form-control', placeholder: s_('ClusterIntegration|Project namespace') + + .form-group + .form-check + = field.check_box :authorization_type, { class: 'form-check-input', disabled: true }, 'rbac', 'abac' + = field.label :authorization_type, s_('ClusterIntegration|RBAC-enabled cluster'), class: 'form-check-label label-bold' + .form-text.text-muted + = s_('ClusterIntegration|Enable this setting if using role-based access control (RBAC).') + = s_('ClusterIntegration|This option will allow you to install applications on RBAC clusters.') + + .form-group + = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success' diff --git a/config/routes.rb b/config/routes.rb index 484e05114be..a69ed97aac6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,9 @@ Rails.application.routes.draw do post '/:application', to: 'clusters/applications#create', as: :install_applications end + scope :platforms do + patch '/:kubernetes_id', to: 'clusters/platforms/kubernetes#update', as: :update_platform_kubernetes + end get :cluster_status, format: :json end end |