Skip to content
Snippets Groups Projects
Commit 1427bdca authored by Kamil Trzcińśki's avatar Kamil Trzcińśki
Browse files

Revert back FetchKubernetesTokenService

parent ccf09824
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -29,7 +29,6 @@ class Projects::ClustersController < Projects::ApplicationController
def new
@cluster = Clusters::Cluster.new.tap do |cluster|
cluster.build_provider_gcp
cluster.build_platform_kubernetes
end
end
 
Loading
Loading
Loading
Loading
@@ -18,8 +18,6 @@ module Clusters
accepts_nested_attributes_for :provider_gcp, update_only: true
accepts_nested_attributes_for :platform_kubernetes, update_only: true
 
validates :provider_type, presence: true
validates :platform_type, presence: true
validates :name, cluster_name: true
validate :restrict_modification, on: :update
 
Loading
Loading
Loading
Loading
@@ -28,7 +28,7 @@ module Clusters
}
 
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
with_options presence: true, if: :active? do
with_options presence: true, if: :enabled? do
validates :api_url, url: true, presence: true
validates :token, presence: true
end
Loading
Loading
@@ -42,10 +42,6 @@ module Clusters
delegate :project, to: :cluster, allow_nil: true
delegate :enabled?, to: :cluster, allow_nil: true
 
def active?
enabled? && api_url.present?
end
class << self
def namespace_for_project(project)
"#{project.path}-#{project.id}"
Loading
Loading
@@ -87,7 +83,7 @@ module Clusters
return raise 'Kubernetes service already configured' unless manages_kubernetes_service?
 
ensure_kubernetes_service.update!(
active: active?,
active: enabled?,
api_url: api_url,
namespace: namespace,
token: token,
Loading
Loading
##
# TODO:
# Almost components in this class were copied from app/models/project_services/kubernetes_service.rb
# We should dry up those classes not to repeat the same code.
# Maybe we should have a special facility (e.g. lib/kubernetes_api) to maintain all Kubernetes API caller.
module Ci
class FetchKubernetesTokenService
attr_reader :api_url, :ca_pem, :username, :password
def initialize(api_url, ca_pem, username, password)
@api_url = api_url
@ca_pem = ca_pem
@username = username
@password = password
end
def execute
read_secrets.each do |secret|
name = secret.dig('metadata', 'name')
if /default-token/ =~ name
token_base64 = secret.dig('data', 'token')
return Base64.decode64(token_base64) if token_base64
end
end
nil
end
private
def read_secrets
kubeclient = build_kubeclient!
kubeclient.get_secrets.as_json
rescue KubeException => err
raise err unless err.error_code == 404
[]
end
def build_kubeclient!(api_path: 'api', api_version: 'v1')
raise "Incomplete settings" unless api_url && username && password
::Kubeclient::Client.new(
join_api_url(api_path),
api_version,
auth_options: { username: username, password: password },
ssl_options: kubeclient_ssl_options,
http_proxy_uri: ENV['http_proxy']
)
end
def join_api_url(api_path)
url = URI.parse(api_url)
prefix = url.path.sub(%r{/+\z}, '')
url.path = [prefix, api_path].join("/")
url.to_s
end
def kubeclient_ssl_options
opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER }
if ca_pem.present?
opts[:cert_store] = OpenSSL::X509::Store.new
opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem))
end
opts
end
end
end
Loading
Loading
@@ -9,10 +9,7 @@ module Clusters
configure_provider
configure_kubernetes
 
ActiveRecord::Base.transaction do
kubernetes.save!
provider.make_created!
end
provider.make_created!
rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e
provider.make_errored!("Failed to request to CloudPlatform; #{e.message}")
rescue KubeException => e
Loading
Loading
@@ -28,23 +25,21 @@ module Clusters
end
 
def configure_kubernetes
kubernetes.api_url = 'https://' + gke_cluster.endpoint
kubernetes.ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate)
kubernetes.username = gke_cluster.master_auth.username
kubernetes.password = gke_cluster.master_auth.password
kubernetes.token = request_kuberenetes_token
cluster.platform_type = :kubernetes
cluster.build_platform_kubernetes(
api_url: 'https://' + gke_cluster.endpoint,
ca_cert: Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate),
username: gke_cluster.master_auth.username,
password: gke_cluster.master_auth.password,
token: request_kuberenetes_token)
end
 
def request_kuberenetes_token
kubernetes.read_secrets.each do |secret|
name = secret.dig('metadata', 'name')
if /default-token/ =~ name
token_base64 = secret.dig('data', 'token')
return Base64.decode64(token_base64) if token_base64
end
end
nil
Ci::FetchKubernetesTokenService.new(
'https://' + gke_cluster.endpoint,
Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate),
gke_cluster.master_auth.username,
gke_cluster.master_auth.password)
end
 
def gke_cluster
Loading
Loading
@@ -57,10 +52,6 @@ module Clusters
def cluster
@cluster ||= provider.cluster
end
def kubernetes
@kubernetes ||= cluster.platform_kubernetes
end
end
end
end
Loading
Loading
@@ -5,8 +5,7 @@
= s_('ClusterIntegration|Read our %{link_to_help_page} on cluster integration.').html_safe % { link_to_help_page: link_to_help_page}
 
= form_for @cluster, url: namespace_project_clusters_path(@project.namespace, @project, @cluster), as: :cluster do |field|
= field.hidden_field :platform_type, :value => 'kubernetes'
= field.hidden_field :provider_type, :value => 'gcp'
= field.hidden_field :provider_type, value: :gcp
= form_errors(@cluster)
.form-group
= field.label :name, s_('ClusterIntegration|Cluster name')
Loading
Loading
@@ -32,10 +31,5 @@
= link_to(s_('ClusterIntegration|See machine types'), 'https://cloud.google.com/compute/docs/machine-types', target: '_blank', rel: 'noopener noreferrer')
= provider_gcp_field.text_field :machine_type, class: 'form-control', placeholder: 'n1-standard-4'
 
= field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field|
.form-group
= platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)')
= platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: Clusters::Platforms::Kubernetes.namespace_for_project(@project)
.form-group
= field.submit s_('ClusterIntegration|Create cluster'), class: 'btn btn-save'
Loading
Loading
@@ -5,8 +5,8 @@ class CreateNewClustersArchitectures < ActiveRecord::Migration
create_table :clusters do |t|
t.references :user, null: false, index: true, foreign_key: { on_delete: :nullify }
 
t.integer :provider_type, null: false
t.integer :platform_type, null: false
t.integer :provider_type
t.integer :platform_type
 
t.datetime_with_timezone :created_at, null: false
t.datetime_with_timezone :updated_at, null: false
Loading
Loading
Loading
Loading
@@ -508,8 +508,8 @@ ActiveRecord::Schema.define(version: 20171017145932) do
 
create_table "clusters", force: :cascade do |t|
t.integer "user_id", null: false
t.integer "provider_type", null: false
t.integer "platform_type", null: false
t.integer "provider_type"
t.integer "platform_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "enabled", default: true
Loading
Loading
require 'spec_helper'
describe Ci::FetchKubernetesTokenService do
describe '#execute' do
subject { described_class.new(api_url, ca_pem, username, password).execute }
let(:api_url) { 'http://111.111.111.111' }
let(:ca_pem) { '' }
let(:username) { 'admin' }
let(:password) { 'xxx' }
context 'when params correct' do
let(:token) { 'xxx.token.xxx' }
let(:secrets_json) do
[
{
'metadata': {
name: metadata_name
},
'data': {
'token': Base64.encode64(token)
}
}
]
end
before do
allow_any_instance_of(Kubeclient::Client)
.to receive(:get_secrets).and_return(secrets_json)
end
context 'when default-token exists' do
let(:metadata_name) { 'default-token-123' }
it { is_expected.to eq(token) }
end
context 'when default-token does not exist' do
let(:metadata_name) { 'another-token-123' }
it { is_expected.to be_nil }
end
end
context 'when api_url is nil' do
let(:api_url) { nil }
it { expect { subject }.to raise_error("Incomplete settings") }
end
context 'when username is nil' do
let(:username) { nil }
it { expect { subject }.to raise_error("Incomplete settings") }
end
context 'when password is nil' do
let(:password) { nil }
it { expect { subject }.to raise_error("Incomplete settings") }
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment