Commit efc9081d authored by Hordur Freyr Yngvason's avatar Hordur Freyr Yngvason Committed by Enrique Alcantara

Expose namespace_per_environment flag for Kubernetes clusters

Adds the ability to use a namespace per project, instead of namespace
per environment, for deployments using GitLab's Kubernetes integration.

See https://gitlab.com/gitlab-org/gitlab/-/issues/38054
parent 1f21a463
......@@ -13,6 +13,10 @@ export default {
type: String,
required: true,
},
namespacePerEnvironmentHelpPath: {
type: String,
required: true,
},
kubernetesIntegrationHelpPath: {
type: String,
required: true,
......@@ -40,6 +44,7 @@ export default {
<eks-cluster-configuration-form
v-if="hasCredentials"
:gitlab-managed-cluster-help-path="gitlabManagedClusterHelpPath"
:namespace-per-environment-help-path="namespacePerEnvironmentHelpPath"
:kubernetes-integration-help-path="kubernetesIntegrationHelpPath"
:external-link-icon="externalLinkIcon"
/>
......
......@@ -37,6 +37,10 @@ export default {
type: String,
required: true,
},
namespacePerEnvironmentHelpPath: {
type: String,
required: true,
},
kubernetesIntegrationHelpPath: {
type: String,
required: true,
......@@ -60,6 +64,7 @@ export default {
'selectedInstanceType',
'nodeCount',
'gitlabManagedCluster',
'namespacePerEnvironment',
'isCreatingCluster',
]),
...mapGetters(['subnetValid']),
......@@ -270,6 +275,20 @@ export default {
false,
);
},
namespacePerEnvironmentHelpText() {
const escapedUrl = escape(this.namespacePerEnvironmentClusterHelpPath);
return sprintf(
s__(
'ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared. %{startLink}More information%{endLink}',
),
{
startLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
endLink: '</a>',
},
false,
);
},
},
mounted() {
this.fetchRegions();
......@@ -290,6 +309,7 @@ export default {
'setInstanceType',
'setNodeCount',
'setGitlabManagedCluster',
'setNamespacePerEnvironment',
]),
...mapRegionsActions({ fetchRegions: 'fetchItems' }),
...mapVpcActions({ fetchVpcs: 'fetchItems' }),
......@@ -519,6 +539,14 @@ export default {
>
<p class="form-text text-muted" v-html="gitlabManagedHelpText"></p>
</div>
<div class="form-group">
<gl-form-checkbox
:checked="namespacePerEnvironment"
@input="setNamespacePerEnvironment({ namespacePerEnvironment: $event })"
>{{ s__('ClusterIntegration|Namespace per environment') }}</gl-form-checkbox
>
<p class="form-text text-muted" v-html="namespacePerEnvironmentHelpText"></p>
</div>
<div class="form-group">
<loading-button
class="js-create-cluster btn-success"
......
......@@ -9,6 +9,7 @@ Vue.use(Vuex);
export default el => {
const {
gitlabManagedClusterHelpPath,
namespacePerEnvironmentHelpPath,
kubernetesIntegrationHelpPath,
accountAndExternalIdsHelpPath,
createRoleArnHelpPath,
......@@ -42,6 +43,7 @@ export default el => {
return createElement('create-eks-cluster', {
props: {
gitlabManagedClusterHelpPath,
namespacePerEnvironmentHelpPath,
kubernetesIntegrationHelpPath,
accountAndExternalIdsHelpPath,
createRoleArnHelpPath,
......
......@@ -55,6 +55,7 @@ export const createCluster = ({ dispatch, state }) => {
name: state.clusterName,
environment_scope: state.environmentScope,
managed: state.gitlabManagedCluster,
namespace_per_environment: state.namespacePerEnvironment,
provider_aws_attributes: {
kubernetes_version: state.kubernetesVersion,
region: state.selectedRegion,
......@@ -114,6 +115,10 @@ export const setGitlabManagedCluster = ({ commit }, payload) => {
commit(types.SET_GITLAB_MANAGED_CLUSTER, payload);
};
export const setNamespacePerEnvironment = ({ commit }, payload) => {
commit(types.SET_NAMESPACE_PER_ENVIRONMENT, payload);
};
export const setInstanceType = ({ commit }, payload) => {
commit(types.SET_INSTANCE_TYPE, payload);
};
......
......@@ -10,6 +10,7 @@ export const SET_SECURITY_GROUP = 'SET_SECURITY_GROUP';
export const SET_INSTANCE_TYPE = 'SET_INSTANCE_TYPE';
export const SET_NODE_COUNT = 'SET_NODE_COUNT';
export const SET_GITLAB_MANAGED_CLUSTER = 'SET_GITLAB_MANAGED_CLUSTER';
export const SET_NAMESPACE_PER_ENVIRONMENT = 'SET_NAMESPACE_PER_ENVIRONMENT';
export const REQUEST_CREATE_ROLE = 'REQUEST_CREATE_ROLE';
export const CREATE_ROLE_SUCCESS = 'CREATE_ROLE_SUCCESS';
export const CREATE_ROLE_ERROR = 'CREATE_ROLE_ERROR';
......
......@@ -37,6 +37,9 @@ export default {
[types.SET_GITLAB_MANAGED_CLUSTER](state, { gitlabManagedCluster }) {
state.gitlabManagedCluster = gitlabManagedCluster;
},
[types.SET_NAMESPACE_PER_ENVIRONMENT](state, { namespacePerEnvironment }) {
state.namespacePerEnvironment = namespacePerEnvironment;
},
[types.REQUEST_CREATE_ROLE](state) {
state.isCreatingRole = true;
state.createRoleError = null;
......
......@@ -30,4 +30,5 @@ export default () => ({
createClusterError: false,
gitlabManagedCluster: true,
namespacePerEnvironment: true,
});
......@@ -180,13 +180,20 @@ class Clusters::ClustersController < Clusters::BaseController
params.permit(:cleanup)
end
def base_permitted_cluster_params
[
:enabled,
:environment_scope,
:managed,
:namespace_per_environment
]
end
def update_params
if cluster.provided_by_user?
params.require(:cluster).permit(
:enabled,
*base_permitted_cluster_params,
:name,
:environment_scope,
:managed,
:base_domain,
:management_project_id,
platform_kubernetes_attributes: [
......@@ -198,9 +205,7 @@ class Clusters::ClustersController < Clusters::BaseController
)
else
params.require(:cluster).permit(
:enabled,
:environment_scope,
:managed,
*base_permitted_cluster_params,
:base_domain,
:management_project_id,
platform_kubernetes_attributes: [
......@@ -212,10 +217,8 @@ class Clusters::ClustersController < Clusters::BaseController
def create_gcp_cluster_params
params.require(:cluster).permit(
:enabled,
*base_permitted_cluster_params,
:name,
:environment_scope,
:managed,
provider_gcp_attributes: [
:gcp_project_id,
:zone,
......@@ -232,10 +235,8 @@ class Clusters::ClustersController < Clusters::BaseController
def create_aws_cluster_params
params.require(:cluster).permit(
:enabled,
*base_permitted_cluster_params,
:name,
:environment_scope,
:managed,
provider_aws_attributes: [
:kubernetes_version,
:key_name,
......@@ -255,10 +256,8 @@ class Clusters::ClustersController < Clusters::BaseController
def create_user_cluster_params
params.require(:cluster).permit(
:enabled,
*base_permitted_cluster_params,
:name,
:environment_scope,
:managed,
platform_kubernetes_attributes: [
:namespace,
:api_url,
......
......@@ -7,6 +7,7 @@ class ClusterEntity < Grape::Entity
expose :enabled
expose :environment_scope
expose :id
expose :namespace_per_environment
expose :name
expose :nodes
expose :provider_type
......
......@@ -42,11 +42,17 @@
class: 'js-gl-managed',
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
- if cluster.allow_user_defined_namespace?
= render('clusters/clusters/namespace', platform_field: platform_field)
= render('clusters/clusters/namespace', platform_field: platform_field, field: field)
.form-group
= field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success'
......@@ -4,6 +4,7 @@
= s_('Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: '<a/>'.html_safe }
- else
.js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'),
'namespace-per-environment-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'),
'create-role-path' => clusterable.authorize_aws_role_path,
'create-cluster-path' => clusterable.create_aws_clusters_path,
'account-id' => Gitlab::CurrentSettings.eks_account_id,
......
......@@ -75,9 +75,15 @@
= field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'),
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
.form-group.js-gke-cluster-creation-submit-container
= field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
class: 'js-gke-cluster-creation-submit btn btn-success', disabled: true
......@@ -46,9 +46,15 @@
class: 'js-gl-managed',
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
= field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field|
- if @user_cluster.allow_user_defined_namespace?
= render('clusters/clusters/namespace', platform_field: platform_kubernetes_field)
......
---
title: Expose the option to use namespace-per-project instead of namespace-per-environment
for Kubernetes clusters
merge_request: 42309
author:
type: changed
......@@ -270,20 +270,30 @@ If your cluster was created before GitLab 12.2, default `KUBE_NAMESPACE` will be
### Custom namespace
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
> - An option to use project-wide namespaces [was added](https://gitlab.com/gitlab-org/gitlab/-/issues/38054) in GitLab 13.5.
The Kubernetes integration defaults to project-environment-specific namespaces
of the form `<project_name>-<project_id>-<environment>` (see [Deployment
The Kubernetes integration provides a `KUBECONFIG` with an auto-generated namespace
to deployment jobs. It defaults to using project-environment specific namespaces
of the form `<prefix>-<environment>`, where `<prefix>` is of the form `<project_name>-<project_id>` (see [Deployment
variables](#deployment-variables)).
For **non**-GitLab-managed clusters, the namespace can be customized using
[`environment:kubernetes:namespace`](../../../ci/environments/index.md#configuring-kubernetes-deployments)
The deployment namespace can be customized in a few ways:
- You can choose between a **namespace per [environment](../../../ci/environments/index.md)** or a **namespace per project**. A namespace per environment is the default and recommended setting, as it prevents the mixing of resources between production and non-production environments.
- When using a project-level cluster, you can additionally customize the namespace prefix. When using namespace-per-environment, the deployment namespace is `<prefix>-<environment>`, but otherwise just `<prefix>`.
- For **non-managed** clusters, the auto-generated namespace is set in the `KUBECONFIG`, but the user is responsible for ensuring its existence. The value can be fully customized using [`environment:kubernetes:namespace`](../../../ci/environments/index.md#configuring-kubernetes-deployments)
in `.gitlab-ci.yml`.
NOTE: **Note:**
When using a [GitLab-managed cluster](#gitlab-managed-clusters), the
namespaces are created automatically prior to deployment and [can not be
customized](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
When you customize the namespace, existing environments remain linked to their current namespaces until you [clear the cluster cache](#clearing-the-cluster-cache).
CAUTION: **Warning:**
By default, anyone who can create a deployment job can access any CI variable within an environment's deployment job. This includes `KUBECONFIG`, which gives access to any secret available to the associated service account in your cluster.
To keep your production credentials safe, consider using [Protected Environments](../../../ci/environments/protected_environments.md), combined with either
- a GitLab-managed cluster and namespace per environment,
- *or*, an environment-scoped cluster per protected environment (the same cluster can be added multiple times with multiple restricted service accounts).
### Integrations
......
......@@ -37,6 +37,7 @@ module API
requires :name, type: String, desc: 'Cluster name'
optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :domain, type: String, desc: 'Cluster base domain'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
......@@ -70,6 +71,7 @@ module API
optional :name, type: String, desc: 'Cluster name'
optional :enabled, type: Boolean, desc: 'Enable or disable Gitlab\'s connection to your Kubernetes cluster'
optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :domain, type: String, desc: 'Cluster base domain'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
......
......@@ -4,7 +4,7 @@ module API
module Entities
class Cluster < Grape::Entity
expose :id, :name, :created_at, :domain
expose :provider_type, :platform_type, :environment_scope, :cluster_type
expose :provider_type, :platform_type, :environment_scope, :cluster_type, :namespace_per_environment
expose :user, using: Entities::UserBasic
expose :platform_kubernetes, using: Entities::Platform::Kubernetes
expose :provider_gcp, using: Entities::Provider::Gcp
......
......@@ -41,6 +41,7 @@ module API
requires :name, type: String, desc: 'Cluster name'
optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :domain, type: String, desc: 'Cluster base domain'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
......@@ -74,6 +75,7 @@ module API
optional :name, type: String, desc: 'Cluster name'
optional :domain, type: String, desc: 'Cluster base domain'
optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
optional :api_url, type: String, desc: 'URL to access the Kubernetes API'
......
......@@ -45,6 +45,7 @@ module API
optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
optional :domain, type: String, desc: 'Cluster base domain'
optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
requires :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
......@@ -78,6 +79,7 @@ module API
optional :name, type: String, desc: 'Cluster name'
optional :domain, type: String, desc: 'Cluster base domain'
optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
optional :management_project_id, type: Integer, desc: 'The ID of the management project'
optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
optional :api_url, type: String, desc: 'URL to access the Kubernetes API'
......
......@@ -5379,10 +5379,10 @@ msgstr ""
msgid "ClusterIntegration|All installed applications and related resources"
msgstr ""
msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster."
msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
msgid "ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster."
msgstr ""
msgid "ClusterIntegration|Alternatively, "
......@@ -5565,6 +5565,12 @@ msgstr ""
msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
msgstr ""
msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
msgstr ""
msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared. %{startLink}More information%{endLink}"
msgstr ""
msgid "ClusterIntegration|Did you know?"
msgstr ""
......@@ -5826,6 +5832,9 @@ msgstr ""
msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
msgstr ""
msgid "ClusterIntegration|Namespace per environment"
msgstr ""
msgid "ClusterIntegration|No IAM Roles found"
msgstr ""
......
......@@ -416,6 +416,7 @@ RSpec.describe Admin::ClustersController do
expect(cluster).to be_user
expect(cluster).to be_kubernetes
expect(cluster).to be_platform_kubernetes_rbac
expect(cluster).to be_namespace_per_environment
end
end
end
......@@ -585,6 +586,7 @@ RSpec.describe Admin::ClustersController do
enabled: false,
name: 'my-new-cluster-name',
managed: false,
namespace_per_environment: false,
base_domain: domain
}
}
......@@ -599,6 +601,7 @@ RSpec.describe Admin::ClustersController do
expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name')
expect(cluster).not_to be_managed
expect(cluster).not_to be_namespace_per_environment
expect(cluster.domain).to eq('test-domain.com')
end
......@@ -624,6 +627,7 @@ RSpec.describe Admin::ClustersController do
enabled: false,
name: 'my-new-cluster-name',
managed: false,
namespace_per_environment: false,
domain: domain
}
}
......@@ -637,6 +641,7 @@ RSpec.describe Admin::ClustersController do
expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name')
expect(cluster).not_to be_managed
expect(cluster).not_to be_namespace_per_environment
end
end
......
......@@ -271,6 +271,7 @@ RSpec.describe Groups::ClustersController do
expect(cluster).to be_kubernetes
expect(cluster.provider_gcp).to be_legacy_abac
expect(cluster).to be_managed
expect(cluster).to be_namespace_per_environment
end
context 'when legacy_abac param is false' do
......@@ -358,6 +359,7 @@ RSpec.describe Groups::ClustersController do
expect(cluster).to be_user
expect(cluster).to be_kubernetes
expect(cluster).to be_managed
expect(cluster).to be_namespace_per_environment
end
end
......@@ -387,6 +389,7 @@ RSpec.describe Groups::ClustersController do
expect(cluster).to be_user
expect(cluster).to be_kubernetes
expect(cluster).to be_platform_kubernetes_rbac
expect(cluster).to be_namespace_per_environment
end
end
......@@ -716,6 +719,7 @@ RSpec.describe Groups::ClustersController do
enabled: false,
name: 'my-new-cluster-name',
managed: false,
namespace_per_environment: false,
domain: domain
}
}
......@@ -729,6 +733,7 @@ RSpec.describe Groups::ClustersController do
expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name')
expect(cluster).not_to be_managed
expect(cluster).not_to be_namespace_per_environment
end
end
......
......@@ -251,6 +251,7 @@ RSpec.describe Projects::ClustersController do
cluster: {
name: 'new-cluster',
managed: '1',
namespace_per_environment: '0',
provider_gcp_attributes: {
gcp_project_id: 'gcp-project-12345',
legacy_abac: legacy_abac_param
......@@ -278,6 +279,7 @@ RSpec.describe Projects::ClustersController do
expect(project.clusters.first).to be_kubernetes
expect(project.clusters.first.provider_gcp).to be_legacy_abac
expect(project.clusters.first.managed?).to be_truthy
expect(project.clusters.first.namespace_per_environment?).to be_falsy
end
context 'when legacy_abac param is false' do
......@@ -369,6 +371,7 @@ RSpec.describe Projects::ClustersController do
expect(project.clusters.first).to be_user
expect(project.clusters.first).to be_kubernetes
expect(project.clusters.first).to be_namespace_per_environment
end
end
......@@ -400,6 +403,7 @@ RSpec.describe Projects::ClustersController do
expect(cluster).to be_user
expect(cluster).to be_kubernetes
expect(cluster).to be_platform_kubernetes_rbac
expect(cluster).to be_namespace_per_environment
end
end
......@@ -726,6 +730,7 @@ RSpec.describe Projects::ClustersController do
enabled: false,
name: 'my-new-cluster-name',
managed: false,
namespace_per_environment: false,
platform_kubernetes_attributes: {
namespace: 'my-namespace'
}
......@@ -742,6 +747,7 @@ RSpec.describe Projects::ClustersController do
expect(cluster.enabled).to be_falsey
expect(cluster.name).to eq('my-new-cluster-name')
expect(cluster).not_to be_managed
expect(cluster).not_to be_namespace_per_environment
expect(cluster.platform_kubernetes.namespace).to eq('my-namespace')
end
......
......@@ -66,6 +66,10 @@ RSpec.describe 'User Cluster', :js do
expect(page.find_field('cluster[platform_kubernetes_attributes][authorization_type]', disabled: true)).to be_checked
end
end
it 'user sees namespace per environment is enabled by default' do
expect(page).to have_checked_field('Namespace per environment')
end
end
context 'when user filled form with invalid parameters' do
......
......@@ -52,6 +52,10 @@ RSpec.describe 'User Cluster', :js do
it 'user sees RBAC is enabled by default' do
expect(page).to have_checked_field('RBAC-enabled cluster')
end
it 'user sees namespace per environment is enabled by default' do
expect(page).to have_checked_field('Namespace per environment')
end
end
context 'when user filled form with invalid parameters' do
......
......@@ -12,6 +12,7 @@ describe('CreateEksCluster', () => {
let vm;
let state;
const gitlabManagedClusterHelpPath = 'gitlab-managed-cluster-help-path';
const namespacePerEnvironmentHelpPath = 'namespace-per-environment-help-path';
const accountAndExternalIdsHelpPath = 'account-and-external-id-help-path';
const createRoleArnHelpPath = 'role-arn-help-path';
const kubernetesIntegrationHelpPath = 'kubernetes-integration';
......@@ -26,6 +27,7 @@ describe('CreateEksCluster', () => {
vm = shallowMount(CreateEksCluster, {
propsData: {
gitlabManagedClusterHelpPath,
namespacePerEnvironmentHelpPath,
accountAndExternalIdsHelpPath,
createRoleArnHelpPath,
externalLinkIcon,
......@@ -53,6 +55,12 @@ describe('CreateEksCluster', () => {
);
});
it('help url for namespace per environment cluster documentation', () => {
expect(vm.find(EksClusterConfigurationForm).props('namespacePerEnvironmentHelpPath')).toBe(
namespacePerEnvironmentHelpPath,
);
});
it('help url for gitlab managed cluster documentation', () => {
expect(vm.find(EksClusterConfigurationForm).props('kubernetesIntegrationHelpPath')).toBe(
kubernetesIntegrationHelpPath,
......
......@@ -169,6 +169,7 @@ describe('EksClusterConfigurationForm', () => {
store,
propsData: {
gitlabManagedClusterHelpPath: '',
namespacePerEnvironmentHelpPath: '',
kubernetesIntegrationHelpPath: '',
externalLinkIcon: '',
},
......
......@@ -14,6 +14,7 @@ import {
SET_ROLE,
SET_SECURITY_GROUP,
SET_GITLAB_MANAGED_CLUSTER,
SET_NAMESPACE_PER_ENVIRONMENT,
SET_INSTANCE_TYPE,
SET_NODE_COUNT,
REQUEST_CREATE_ROLE,
......@@ -40,6 +41,7 @@ describe('EKS Cluster Store Actions', () => {
let instanceType;
let nodeCount;
let gitlabManagedCluster;
let namespacePerEnvironment;
let mock;
let state;
let newClusterUrl;
......@@ -57,6 +59,7 @@ describe('EKS Cluster Store Actions', () => {
instanceType = 'small-1';
nodeCount = '5';
gitlabManagedCluster = true;
namespacePerEnvironment = true;
newClusterUrl = '/clusters/1';
......@@ -76,19 +79,20 @@ describe('EKS Cluster Store Actions', () => {
});
it.each`
action | mutation | payload | payloadDescription
${'setClusterName'} | ${SET_CLUSTER_NAME} | ${{ clusterName }} | ${'cluster name'}
${'setEnvironmentScope'} | ${SET_ENVIRONMENT_SCOPE} | ${{ environmentScope }} | ${'environment scope'}
${'setKubernetesVersion'} | ${SET_KUBERNETES_VERSION} | ${{ kubernetesVersion }} | ${'kubernetes version'}
${'setRole'} | ${SET_ROLE} | ${{ role }} | ${'role'}
${'setRegion'} | ${SET_REGION} | ${{ region }} | ${'region'}
${'setKeyPair'} | ${SET_KEY_PAIR} | ${{ keyPair }} | ${'key pair'}
${'setVpc'} | ${SET_VPC} | ${{ vpc }} | ${'vpc'}
${'setSubnet'} | ${SET_SUBNET} | ${{ subnet }} | ${'subnet'}
${'setSecurityGroup'} | ${SET_SECURITY_GROUP} | ${{ securityGroup }} | ${'securityGroup'}
${'setInstanceType'} | ${SET_INSTANCE_TYPE} | ${{ instanceType }} | ${'instance type'}
${'setNodeCount'} | ${SET_NODE_COUNT} | ${{ nodeCount }} | ${'node count'}
${'setGitlabManagedCluster'} | ${SET_GITLAB_MANAGED_CLUSTER} | ${gitlabManagedCluster} | ${'gitlab managed cluster'}
action | mutation | payload | payloadDescription
${'setClusterName'} | ${SET_CLUSTER_NAME} | ${{ clusterName }} | ${'cluster name'}
${'setEnvironmentScope'} | ${SET_ENVIRONMENT_SCOPE} | ${{ environmentScope }} | ${'environment scope'}
${'setKubernetesVersion'} | ${SET_KUBERNETES_VERSION} | ${{ kubernetesVersion }} | ${'kubernetes version'}
${'setRole'} | ${SET_ROLE} | ${{ role }} | ${'role'}
${'setRegion'} | ${SET_REGION} | ${{ region }} | ${'region'}
${'setKeyPair'} | ${SET_KEY_PAIR} | ${{ keyPair }} | ${'key pair'}
${'setVpc'} | ${SET_VPC} | ${{ vpc }} | ${'vpc'}
${'setSubnet'} | ${SET_SUBNET} | ${{ subnet }} | ${'subnet'}
${'setSecurityGroup'} | ${SET_SECURITY_GROUP} | ${{ securityGroup }} | ${'securityGroup'}
${'setInstanceType'} | ${SET_INSTANCE_TYPE} | ${{ instanceType }} | ${'instance type'}
${'setNodeCount'} | ${SET_NODE_COUNT} | ${{ nodeCount }} | ${'node count'}
${'setGitlabManagedCluster'} | ${SET_GITLAB_MANAGED_CLUSTER} | ${gitlabManagedCluster} | ${'gitlab managed cluster'}
${'setNamespacePerEnvironment'} | ${SET_NAMESPACE_PER_ENVIRONMENT} | ${namespacePerEnvironment} | ${'namespace per environment'}
`(`$action commits $mutation with $payloadDescription payload`, data => {
const { action, mutation, payload } = data;
......@@ -179,6 +183,7 @@ describe('EKS Cluster Store Actions', () => {
name: clusterName,
environment_scope: environmentScope,
managed: gitlabManagedCluster,
namespace_per_environment: namespacePerEnvironment,
provider_aws_attributes: {
kubernetes_version: kubernetesVersion,
region,
......@@ -204,6 +209,7 @@ describe('EKS Cluster Store Actions', () => {
selectedInstanceType: instanceType,
nodeCount,
gitlabManagedCluster,
namespacePerEnvironment,
});
});
......
......@@ -47,6 +47,7 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
it { is_expected.to delegate_method(:external_hostname).to(:application_ingress).with_prefix }
it { is_expected.to respond_to :project }
it { is_expected.to be_namespace_per_environment }
describe 'applications have inverse_of: :cluster option' do
let(:cluster) { create(:cluster) }
......
......@@ -162,6 +162,7 @@ RSpec.describe ::API::Admin::InstanceClusters do
name: 'test-instance-cluster',
domain: 'domain.example.com',
managed: false,
namespace_per_environment: false,
platform_kubernetes_attributes: platform_kubernetes_attributes,
clusterable: clusterable
}
......@@ -206,6 +207,7 @@ RSpec.describe ::API::Admin::InstanceClusters do
expect(cluster_result.enabled).to eq(true)
expect(platform_kubernetes.authorization_type).to eq('rbac')
expect(cluster_result.managed).to be_falsy
expect(cluster_result.namespace_per_environment).to eq(false)
expect(platform_kubernetes.api_url).to eq("https://example.com")
expect(platform_kubernetes.token).to eq('sample-token')
end
......@@ -235,6 +237,22 @@ RSpec.describe ::API::Admin::InstanceClusters do
end
end
context 'when namespace_per_environment is not set' do
let(:cluster_params) do
{
name: 'test-cluster',
domain: 'domain.example.com',
platform_kubernetes_attributes: platform_kubernetes_attributes
}
end
it 'defaults to true' do
cluster_result = Clusters::Cluster.find(json_response['id'])
expect(cluster_result).to be_namespace_per_environment
end
end
context 'when an instance cluster already exists' do
it 'allows user to add multiple clusters' do
post api('/admin/clusters/add', admin_user), params: multiple_cluster_params
......
......@@ -172,6 +172,7 @@ RSpec.describe API::GroupClusters do
name: 'test-cluster',
domain: 'domain.example.com',
managed: false,
namespace_per_environment: false,
platform_kubernetes_attributes: platform_kubernetes_attributes,
management_project_id: management_project_id
}
......@@ -206,6 +207,7 @@ RSpec.describe API::GroupClusters do
expect(cluster_result.domain).to eq('domain.example.com')
expect(cluster_result.managed).to be_falsy
expect(cluster_result.management_project_id).to eq management_project_id
expect(cluster_result.namespace_per_environment).to eq(false)
expect(platform_kubernetes.rbac?).to be_truthy
expect(platform_kubernetes.api_url).to eq(api_url)
expect(platform_kubernetes.token).to eq('sample-token')
......@@ -237,6 +239,22 @@ RSpec.describe API::GroupClusters do
end
end
context 'when namespace_per_environment is not set' do
let(:cluster_params) do
{
name: 'test-cluster',
domain: 'domain.example.com',
platform_kubernetes_attributes: platform_kubernetes_attributes
}
end
it 'defaults to true' do
cluster_result = Clusters::Cluster.find(json_response['id'])
expect(cluster_result).to be_namespace_per_environment
end
end
context 'current user does not have access to management_project_id' do
let(:management_project_id) { create(:project).id }
......
......@@ -171,6 +171,7 @@ RSpec.describe API::ProjectClusters do
name: 'test-cluster',
domain: 'domain.example.com',
managed: false,
namespace_per_environment: false,
platform_kubernetes_attributes: platform_kubernetes_attributes,
management_project_id: management_project_id
}
......@@ -202,6 +203,7 @@ RSpec.describe API::ProjectClusters do
expect(cluster_result.domain).to eq('domain.example.com')
expect(cluster_result.managed).to be_falsy
expect(cluster_result.management_project_id).to eq management_project_id
expect(cluster_result.namespace_per_environment).to eq(false)
expect(platform_kubernetes.rbac?).to be_truthy
expect(platform_kubernetes.api_url).to eq(api_url)
expect(platform_kubernetes.namespace).to eq(namespace)
......@@ -235,6 +237,22 @@ RSpec.describe API::ProjectClusters do
end
end
context 'when namespace_per_environment is not set' do
let(:cluster_params) do
{
name: 'test-cluster',
domain: 'domain.example.com',
platform_kubernetes_attributes: platform_kubernetes_attributes
}
end
it 'defaults to true' do
cluster_result = Clusters::Cluster.find(json_response['id'])
expect(cluster_result).to be_namespace_per_environment
end
end
context 'current user does not have access to management_project_id' do
let(:management_project_id) { create(:project).id }
......
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