Commit ebbaa4cf authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '40473-api-support-for-kubernetes-integration-ee' into 'master'

EE port  API Support for Kubernetes integration

Closes gitlab-ce#40473

See merge request gitlab-org/gitlab-ee!8994
parents ec1f20a2 39486f33
---
title: Add API Support for Kubernetes integration
merge_request: 23922
author:
type: added
# frozen_string_literal: true
module EE
module API
module ProjectClusters
extend ActiveSupport::Concern
prepended do
helpers do
params :create_params_ee do
optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
end
params :update_params_ee do
optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe API::ProjectClusters do
include KubernetesHelpers
let(:current_user) { create(:user) }
let(:project) { create(:project, :repository) }
shared_context 'kubernetes calls stubbed' do
before do
stub_kubeclient_discover(api_url)
stub_kubeclient_get_namespace(api_url, namespace: namespace)
stub_kubeclient_get_service_account(api_url, "#{namespace}-service-account", namespace: namespace)
stub_kubeclient_put_service_account(api_url, "#{namespace}-service-account", namespace: namespace)
stub_kubeclient_get_secret(
api_url,
{
metadata_name: "#{namespace}-token",
token: Base64.encode64('sample-token'),
namespace: namespace
}
)
stub_kubeclient_put_secret(api_url, "#{namespace}-token", namespace: namespace)
stub_kubeclient_get_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace)
stub_kubeclient_put_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace)
end
end
before do
project.add_maintainer(current_user)
end
describe 'POST /projects/:id/clusters/user' do
include_context 'kubernetes calls stubbed'
let(:api_url) { 'https://kubernetes.example.com' }
let(:namespace) { project.path }
let(:platform_kubernetes_attributes) do
{
api_url: api_url,
token: 'sample-token',
namespace: namespace
}
end
let(:cluster_params) do
{
name: 'test-cluster',
environment_scope: 'production/*',
platform_kubernetes_attributes: platform_kubernetes_attributes
}
end
before do
post api("/projects/#{project.id}/clusters/user", current_user), params: cluster_params
end
context 'when user sets specific environment scope' do
it 'should create a cluster with that specific environment' do
expect(json_response['environment_scope']).to eq('production/*')
end
end
context 'when does not set an specific environment scope' do
let(:cluster_params) do
{
name: 'test-cluster',
platform_kubernetes_attributes: platform_kubernetes_attributes
}
end
it 'should set default environment' do
expect(json_response['environment_scope']).to eq('*')
end
end
end
describe 'PUT /projects/:id/clusters/:cluster_id' do
include_context 'kubernetes calls stubbed'
let(:api_url) { 'https://kubernetes.example.com' }
let(:namespace) { project.path }
let(:update_params) do
{
namespace: namespace,
environment_scope: 'test/*'
}
end
before do
put api("/projects/#{project.id}/clusters/#{cluster.id}", current_user), params: update_params
cluster.reload
end
context 'With a GCP cluster' do
let(:cluster) do
create(:cluster, :project, :provided_by_gcp,
projects: [project])
end
it 'should update the environment scope' do
expect(cluster.environment_scope).to eq('test/*')
end
end
context 'With an user cluster' do
let(:cluster) do
create(:cluster, :project, :provided_by_user,
projects: [project])
end
it 'should update the environment scope' do
expect(cluster.environment_scope).to eq('test/*')
end
end
end
end
...@@ -139,6 +139,7 @@ module API ...@@ -139,6 +139,7 @@ module API
mount ::API::Pipelines mount ::API::Pipelines
mount ::API::PipelineSchedules mount ::API::PipelineSchedules
mount ::API::ProjectApprovals mount ::API::ProjectApprovals
mount ::API::ProjectClusters
mount ::API::ProjectExport mount ::API::ProjectExport
mount ::API::ProjectImport mount ::API::ProjectImport
mount ::API::ProjectHooks mount ::API::ProjectHooks
......
...@@ -1587,6 +1587,39 @@ module API ...@@ -1587,6 +1587,39 @@ module API
expose :from_content expose :from_content
expose :to_content expose :to_content
end end
module Platform
class Kubernetes < Grape::Entity
expose :api_url
expose :namespace
expose :authorization_type
expose :ca_cert
end
end
module Provider
class Gcp < Grape::Entity
expose :cluster_id
expose :status_name
expose :gcp_project_id
expose :zone
expose :machine_type
expose :num_nodes
expose :endpoint
end
end
class Cluster < Grape::Entity
expose :id, :name, :created_at
expose :provider_type, :platform_type, :environment_scope, :cluster_type
expose :user, using: Entities::UserBasic
expose :platform_kubernetes, using: Entities::Platform::Kubernetes
expose :provider_gcp, using: Entities::Provider::Gcp
end
class ClusterProject < Cluster
expose :project, using: Entities::BasicProjectDetails
end
end end
end end
......
# frozen_string_literal: true
module API
class ProjectClusters < Grape::API
include PaginationParams
before { authenticate! }
# EE::API::ProjectClusters will
# override these methods
helpers do
params :create_params_ee do
end
params :update_params_ee do
end
end
prepend EE::API::ProjectClusters
params do
requires :id, type: String, desc: 'The ID of the project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all clusters from the project' do
detail 'This feature was introduced in GitLab 11.7.'
success Entities::Cluster
end
params do
use :pagination
end
get ':id/clusters' do
authorize! :read_cluster, user_project
present paginate(clusters_for_current_user), with: Entities::Cluster
end
desc 'Get specific cluster for the project' do
detail 'This feature was introduced in GitLab 11.7.'
success Entities::ClusterProject
end
params do
requires :cluster_id, type: Integer, desc: 'The cluster ID'
end
get ':id/clusters/:cluster_id' do
authorize! :read_cluster, cluster
present cluster, with: Entities::ClusterProject
end
desc 'Adds an existing cluster' do
detail 'This feature was introduced in GitLab 11.7.'
success Entities::ClusterProject
end
params do
requires :name, type: String, desc: 'Cluster name'
optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
requires :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
requires :api_url, type: String, allow_blank: false, desc: 'URL to access the Kubernetes API'
requires :token, type: String, desc: 'Token to authenticate against Kubernetes'
optional :ca_cert, type: String, desc: 'TLS certificate (needed if API is using a self-signed TLS certificate)'
optional :namespace, type: String, desc: 'Unique namespace related to Project'
optional :authorization_type, type: String, values: Clusters::Platforms::Kubernetes.authorization_types.keys, default: 'rbac', desc: 'Cluster authorization type, defaults to RBAC'
end
use :create_params_ee
end
post ':id/clusters/user' do
authorize! :create_cluster, user_project
user_cluster = ::Clusters::CreateService
.new(current_user, create_cluster_user_params)
.execute
if user_cluster.persisted?
present user_cluster, with: Entities::ClusterProject
else
render_validation_error!(user_cluster)
end
end
desc 'Update an existing cluster' do
detail 'This feature was introduced in GitLab 11.7.'
success Entities::ClusterProject
end
params do
requires :cluster_id, type: Integer, desc: 'The cluster ID'
optional :name, type: String, desc: 'Cluster name'
optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
optional :api_url, type: String, desc: 'URL to access the Kubernetes API'
optional :token, type: String, desc: 'Token to authenticate against Kubernetes'
optional :ca_cert, type: String, desc: 'TLS certificate (needed if API is using a self-signed TLS certificate)'
optional :namespace, type: String, desc: 'Unique namespace related to Project'
end
use :update_params_ee
end
put ':id/clusters/:cluster_id' do
authorize! :update_cluster, cluster
update_service = Clusters::UpdateService.new(current_user, update_cluster_params)
if update_service.execute(cluster)
present cluster, with: Entities::ClusterProject
else
render_validation_error!(cluster)
end
end
desc 'Remove a cluster' do
detail 'This feature was introduced in GitLab 11.7.'
success Entities::ClusterProject
end
params do
requires :cluster_id, type: Integer, desc: 'The Cluster ID'
end
delete ':id/clusters/:cluster_id' do
authorize! :admin_cluster, cluster
destroy_conditionally!(cluster)
end
end
helpers do
def clusters_for_current_user
@clusters_for_current_user ||= ClustersFinder.new(user_project, current_user, :all).execute
end
def cluster
@cluster ||= clusters_for_current_user.find(params[:cluster_id])
end
def create_cluster_user_params
declared_params.merge({
provider_type: :user,
platform_type: :kubernetes,
clusterable: user_project
})
end
def update_cluster_params
declared_params(include_missing: false).without(:cluster_id)
end
end
end
end
This diff is collapsed.
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