2018-12-05 23:21:45 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
RSpec.describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
|
2018-12-05 23:21:45 +05:30
|
|
|
include KubernetesHelpers
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
let(:api_url) { 'http://111.111.111.111' }
|
|
|
|
let(:platform_kubernetes) { cluster.platform_kubernetes }
|
|
|
|
let(:cluster_project) { cluster.cluster_project }
|
|
|
|
let(:project) { cluster_project.project }
|
|
|
|
let(:cluster) do
|
|
|
|
create(:cluster,
|
|
|
|
:project, :provided_by_gcp,
|
|
|
|
platform_kubernetes: create(:cluster_platform_kubernetes, :configured))
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:kubeclient) do
|
|
|
|
Gitlab::Kubernetes::KubeClient.new(
|
|
|
|
api_url,
|
|
|
|
auth_options: { username: 'admin', password: 'xxx' }
|
|
|
|
)
|
|
|
|
end
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
shared_examples 'creates service account and token' do
|
|
|
|
it 'creates a kubernetes service account' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:post, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts").with(
|
|
|
|
body: hash_including(
|
|
|
|
kind: 'ServiceAccount',
|
|
|
|
metadata: { name: service_account_name, namespace: namespace }
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
it 'creates a kubernetes secret' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:post, api_url + "/api/v1/namespaces/#{namespace}/secrets").with(
|
|
|
|
body: hash_including(
|
|
|
|
kind: 'Secret',
|
|
|
|
metadata: {
|
|
|
|
name: token_name,
|
|
|
|
namespace: namespace,
|
|
|
|
annotations: {
|
|
|
|
'kubernetes.io/service-account.name': service_account_name
|
|
|
|
}
|
|
|
|
},
|
|
|
|
type: 'kubernetes.io/service-account-token'
|
|
|
|
)
|
2018-12-05 23:21:45 +05:30
|
|
|
)
|
|
|
|
end
|
2018-12-13 13:39:08 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
stub_kubeclient_discover(api_url)
|
|
|
|
stub_kubeclient_get_namespace(api_url, namespace: namespace)
|
2019-02-15 15:39:39 +05:30
|
|
|
|
|
|
|
stub_kubeclient_get_service_account_error(api_url, service_account_name, namespace: namespace)
|
|
|
|
stub_kubeclient_create_service_account(api_url, namespace: namespace)
|
|
|
|
|
|
|
|
stub_kubeclient_get_secret_error(api_url, token_name, namespace: namespace)
|
2018-12-13 13:39:08 +05:30
|
|
|
stub_kubeclient_create_secret(api_url, namespace: namespace)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.gitlab_creator' do
|
|
|
|
let(:namespace) { 'default' }
|
|
|
|
let(:service_account_name) { 'gitlab' }
|
|
|
|
let(:token_name) { 'gitlab-token' }
|
|
|
|
|
|
|
|
subject { described_class.gitlab_creator(kubeclient, rbac: rbac).execute }
|
|
|
|
|
|
|
|
context 'with ABAC cluster' do
|
|
|
|
let(:rbac) { false }
|
|
|
|
|
|
|
|
it_behaves_like 'creates service account and token'
|
|
|
|
end
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
context 'with RBAC cluster' do
|
|
|
|
let(:rbac) { true }
|
2019-02-15 15:39:39 +05:30
|
|
|
let(:cluster_role_binding_name) { 'gitlab-admin' }
|
2018-12-05 23:21:45 +05:30
|
|
|
|
|
|
|
before do
|
2018-12-13 13:39:08 +05:30
|
|
|
cluster.platform_kubernetes.rbac!
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
stub_kubeclient_put_cluster_role_binding(api_url, cluster_role_binding_name)
|
2018-12-13 13:39:08 +05:30
|
|
|
end
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
it_behaves_like 'creates service account and token'
|
|
|
|
|
2019-07-07 11:18:12 +05:30
|
|
|
it 'creates a cluster role binding with cluster-admin access' do
|
2018-12-13 13:39:08 +05:30
|
|
|
subject
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/gitlab-admin").with(
|
2018-12-13 13:39:08 +05:30
|
|
|
body: hash_including(
|
|
|
|
metadata: { name: 'gitlab-admin' },
|
|
|
|
roleRef: {
|
|
|
|
apiGroup: 'rbac.authorization.k8s.io',
|
|
|
|
kind: 'ClusterRole',
|
|
|
|
name: 'cluster-admin'
|
|
|
|
},
|
|
|
|
subjects: [
|
|
|
|
{
|
|
|
|
kind: 'ServiceAccount',
|
|
|
|
name: service_account_name,
|
|
|
|
namespace: namespace
|
|
|
|
}
|
|
|
|
]
|
2018-12-05 23:21:45 +05:30
|
|
|
)
|
2018-12-13 13:39:08 +05:30
|
|
|
)
|
2018-12-05 23:21:45 +05:30
|
|
|
end
|
2018-12-13 13:39:08 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '.namespace_creator' do
|
|
|
|
let(:namespace) { "#{project.path}-#{project.id}" }
|
2020-03-13 15:44:24 +05:30
|
|
|
let(:namespace_labels) { { app: project.full_path_slug, env: "staging" } }
|
2018-12-13 13:39:08 +05:30
|
|
|
let(:service_account_name) { "#{namespace}-service-account" }
|
|
|
|
let(:token_name) { "#{namespace}-token" }
|
|
|
|
|
|
|
|
subject do
|
|
|
|
described_class.namespace_creator(
|
|
|
|
kubeclient,
|
|
|
|
service_account_name: service_account_name,
|
|
|
|
service_account_namespace: namespace,
|
2020-03-13 15:44:24 +05:30
|
|
|
service_account_namespace_labels: namespace_labels,
|
2018-12-13 13:39:08 +05:30
|
|
|
rbac: rbac
|
|
|
|
).execute
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with ABAC cluster' do
|
|
|
|
let(:rbac) { false }
|
|
|
|
|
|
|
|
it_behaves_like 'creates service account and token'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'With RBAC enabled cluster' do
|
|
|
|
let(:rbac) { true }
|
2019-02-15 15:39:39 +05:30
|
|
|
let(:role_binding_name) { "gitlab-#{namespace}"}
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
before do
|
|
|
|
cluster.platform_kubernetes.rbac!
|
2018-12-05 23:21:45 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
stub_kubeclient_delete_role_binding(api_url, role_binding_name, namespace: namespace)
|
2020-05-24 23:13:21 +05:30
|
|
|
stub_kubeclient_put_role_binding(api_url, role_binding_name, namespace: namespace)
|
2019-12-04 20:38:33 +05:30
|
|
|
stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace)
|
|
|
|
stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace)
|
2019-12-26 22:10:19 +05:30
|
|
|
stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace)
|
|
|
|
stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace)
|
2021-04-17 20:07:23 +05:30
|
|
|
stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME, namespace: namespace)
|
|
|
|
stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME, namespace: namespace)
|
2018-12-05 23:21:45 +05:30
|
|
|
end
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
it 'creates a namespace object' do
|
|
|
|
kubernetes_namespace = double(Gitlab::Kubernetes::Namespace)
|
|
|
|
expect(Gitlab::Kubernetes::Namespace).to(
|
|
|
|
receive(:new).with(namespace, kubeclient, labels: namespace_labels).and_return(kubernetes_namespace)
|
|
|
|
)
|
|
|
|
expect(kubernetes_namespace).to receive(:ensure_exists!)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
it_behaves_like 'creates service account and token'
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
it 'creates a namespaced role binding with admin access' do
|
|
|
|
subject
|
2018-12-13 13:39:08 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{role_binding_name}").with(
|
|
|
|
body: hash_including(
|
|
|
|
metadata: { name: "gitlab-#{namespace}", namespace: "#{namespace}" },
|
|
|
|
roleRef: {
|
|
|
|
apiGroup: 'rbac.authorization.k8s.io',
|
|
|
|
kind: 'ClusterRole',
|
|
|
|
name: 'admin'
|
|
|
|
},
|
|
|
|
subjects: [
|
|
|
|
{
|
|
|
|
kind: 'ServiceAccount',
|
|
|
|
name: service_account_name,
|
|
|
|
namespace: namespace
|
|
|
|
}
|
|
|
|
]
|
2018-12-05 23:21:45 +05:30
|
|
|
)
|
2021-01-29 00:20:46 +05:30
|
|
|
)
|
2018-12-05 23:21:45 +05:30
|
|
|
end
|
2019-09-30 21:07:59 +05:30
|
|
|
|
2019-12-26 22:10:19 +05:30
|
|
|
it 'creates a role binding granting crossplane database permissions to the service account' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME}").with(
|
|
|
|
body: hash_including(
|
|
|
|
metadata: {
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME,
|
|
|
|
namespace: namespace
|
|
|
|
},
|
|
|
|
roleRef: {
|
|
|
|
apiGroup: 'rbac.authorization.k8s.io',
|
|
|
|
kind: 'Role',
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME
|
|
|
|
},
|
|
|
|
subjects: [
|
|
|
|
{
|
|
|
|
kind: 'ServiceAccount',
|
|
|
|
name: service_account_name,
|
|
|
|
namespace: namespace
|
|
|
|
}
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2019-09-30 21:07:59 +05:30
|
|
|
it 'creates a role and role binding granting knative serving permissions to the service account' do
|
|
|
|
subject
|
|
|
|
|
2019-12-04 20:38:33 +05:30
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME}").with(
|
2019-09-30 21:07:59 +05:30
|
|
|
body: hash_including(
|
|
|
|
metadata: {
|
2019-12-04 20:38:33 +05:30
|
|
|
name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME,
|
2019-09-30 21:07:59 +05:30
|
|
|
namespace: namespace
|
|
|
|
},
|
|
|
|
rules: [{
|
|
|
|
apiGroups: %w(serving.knative.dev),
|
|
|
|
resources: %w(configurations configurationgenerations routes revisions revisionuids autoscalers services),
|
|
|
|
verbs: %w(get list create update delete patch watch)
|
|
|
|
}]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
2019-12-26 22:10:19 +05:30
|
|
|
|
|
|
|
it 'creates a role and role binding granting crossplane database permissions to the service account' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME}").with(
|
|
|
|
body: hash_including(
|
|
|
|
metadata: {
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME,
|
|
|
|
namespace: namespace
|
|
|
|
},
|
|
|
|
rules: [{
|
|
|
|
apiGroups: %w(database.crossplane.io),
|
|
|
|
resources: %w(postgresqlinstances),
|
|
|
|
verbs: %w(get list create watch)
|
|
|
|
}]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
2021-04-17 20:07:23 +05:30
|
|
|
|
|
|
|
it 'creates a role granting cilium permissions to the service account' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME}").with(
|
|
|
|
body: hash_including(
|
|
|
|
metadata: {
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME,
|
|
|
|
namespace: namespace
|
|
|
|
},
|
|
|
|
rules: [{
|
|
|
|
apiGroups: %w(cilium.io),
|
|
|
|
resources: %w(ciliumnetworkpolicies),
|
|
|
|
verbs: %w(get list create update patch)
|
|
|
|
}]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'creates a role binding granting cilium permissions to the service account' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME}").with(
|
|
|
|
body: hash_including(
|
|
|
|
metadata: {
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME,
|
|
|
|
namespace: namespace
|
|
|
|
},
|
|
|
|
roleRef: {
|
|
|
|
apiGroup: 'rbac.authorization.k8s.io',
|
|
|
|
kind: 'Role',
|
|
|
|
name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME
|
|
|
|
},
|
|
|
|
subjects: [{
|
|
|
|
kind: 'ServiceAccount',
|
|
|
|
name: service_account_name,
|
|
|
|
namespace: namespace
|
|
|
|
}]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
2018-12-05 23:21:45 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|