Commit a03b8576 authored by Dan Davison's avatar Dan Davison

Add k3s provider

Add k3s specs
Remove unused k3s_hostname method
Remove :requires_admin tag from k8s spec
Always set allow local requests before and after
parent 6977b861
......@@ -3,7 +3,7 @@
.form-group
%h5= s_('ClusterIntegration|Integration status')
%label.append-bottom-0.js-cluster-enable-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: @cluster.enabled?, label: s_("ClusterIntegration|Toggle Kubernetes cluster"), disabled: !can?(current_user, :update_cluster, @cluster) do
= render "shared/buttons/project_feature_toggle", is_checked: @cluster.enabled?, label: s_("ClusterIntegration|Toggle Kubernetes cluster"), disabled: !can?(current_user, :update_cluster, @cluster), data: { qa_selector: 'integration_status_toggle' } do
= field.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
.form-text.text-muted= s_('ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.')
......@@ -22,7 +22,7 @@
.form-group
%h5= s_('ClusterIntegration|Base domain')
= field.text_field :base_domain, class: 'col-md-6 form-control js-select-on-focus qa-base-domain'
= field.text_field :base_domain, class: 'col-md-6 form-control js-select-on-focus', data: { qa_selector: 'base_domain_field' }
.form-text.text-muted
- auto_devops_url = help_page_path('topics/autodevops/index')
- auto_devops_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: auto_devops_url }
......@@ -37,4 +37,4 @@
- if can?(current_user, :update_cluster, @cluster)
.form-group
= field.submit _('Save changes'), class: 'btn btn-success qa-save-domain'
= field.submit _('Save changes'), class: 'btn btn-success', data: { qa_selector: 'save_changes_button' }
......@@ -54,4 +54,4 @@
= render('clusters/clusters/namespace', platform_field: platform_kubernetes_field)
.form-group
= field.submit s_('ClusterIntegration|Add Kubernetes cluster'), class: 'btn btn-success'
= field.submit s_('ClusterIntegration|Add Kubernetes cluster'), class: 'btn btn-success', data: { qa_selector: 'add_kubernetes_cluster_button' }
......@@ -427,6 +427,7 @@ module QA
autoload :Gcloud, 'qa/service/cluster_provider/gcloud'
autoload :Minikube, 'qa/service/cluster_provider/minikube'
autoload :K3d, 'qa/service/cluster_provider/k3d'
autoload :K3s, 'qa/service/cluster_provider/k3s'
end
module DockerRun
......@@ -438,6 +439,7 @@ module QA
autoload :GitlabRunner, 'qa/service/docker_run/gitlab_runner'
autoload :MailHog, 'qa/service/docker_run/mail_hog'
autoload :SamlIdp, 'qa/service/docker_run/saml_idp'
autoload :K3s, 'qa/service/docker_run/k3s'
end
end
......
......@@ -11,7 +11,7 @@ module QA
element :api_url, 'url_field :api_url' # rubocop:disable QA/ElementWithPattern
element :ca_certificate, 'text_area :ca_cert' # rubocop:disable QA/ElementWithPattern
element :token, 'text_field :token' # rubocop:disable QA/ElementWithPattern
element :add_cluster_button, "submit s_('ClusterIntegration|Add Kubernetes cluster')" # rubocop:disable QA/ElementWithPattern
element :add_kubernetes_cluster_button
element :rbac_checkbox
end
......@@ -32,7 +32,7 @@ module QA
end
def add_cluster!
click_on 'Add Kubernetes cluster'
click_element :add_kubernetes_cluster_button, Page::Project::Operations::Kubernetes::Show
end
def uncheck_rbac!
......
......@@ -11,14 +11,20 @@ module QA
end
view 'app/views/clusters/clusters/_form.html.haml' do
element :base_domain
element :save_domain
element :integration_status_toggle, required: true
element :base_domain_field, required: true
element :save_changes_button, required: true
end
view 'app/assets/javascripts/clusters/components/application_row.vue' do
element :install_button
element :uninstall_button
end
def install!(application_name)
within_element(application_name) do
has_element?(:install_button, application: application_name, wait: 30)
click_on 'Install' # TODO replace with click_element
click_element :install_button
end
end
......@@ -41,11 +47,11 @@ module QA
end
def set_domain(domain)
fill_element :base_domain, domain
fill_element :base_domain_field, domain
end
def save_domain
click_element :save_domain
click_element :save_changes_button, Page::Project::Operations::Kubernetes::Show
end
end
end
......
# frozen_string_literal: true
module QA
module Service
module ClusterProvider
class K3s < Base
def validate_dependencies
Runtime::ApplicationSettings.set_application_settings(allow_local_requests_from_web_hooks_and_services: true)
end
def setup
@k3s = Service::DockerRun::K3s.new.tap do |k3s|
k3s.register!
shell "kubectl config set-cluster k3s --server https://#{k3s.host_name}:6443 --insecure-skip-tls-verify"
shell 'kubectl config set-credentials default --username=node --password=some-secret'
shell 'kubectl config set-context k3s --cluster=k3s --user=default'
shell 'kubectl config use-context k3s'
wait_for_server(k3s.host_name) do
shell 'kubectl version'
wait_for_namespaces do
# install local storage
shell 'kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml'
# patch local storage
shell %(kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}')
end
end
end
end
def teardown
Runtime::ApplicationSettings.set_application_settings(allow_local_requests_from_web_hooks_and_services: false)
@k3s&.remove!
end
def set_credentials(admin_user)
end
# Fetch "real" certificate
# See https://github.com/rancher/k3s/issues/27
def filter_credentials(credentials)
kubeconfig = YAML.safe_load(@k3s.kubeconfig)
ca_certificate = kubeconfig.dig('clusters', 0, 'cluster', 'certificate-authority-data')
credentials.merge('data' => credentials['data'].merge('ca.crt' => ca_certificate))
end
private
def wait_for_server(host_name)
print "Waiting for K3s server at `https://#{host_name}:6443` to become available "
60.times do
if service_available?('kubectl version')
return yield if block_given?
return true
end
sleep 1
print '.'
end
raise 'K3s server never came up'
end
def wait_for_namespaces
print 'Waiting for k8s namespaces to populate'
60.times do
if service_available?('kubectl get pods --all-namespaces | grep --silent "Running"')
return yield if block_given?
return true
end
sleep 1
print '.'
end
raise 'K8s namespaces didnt populate correctly'
end
def service_available?(command)
system("#{command} > /dev/null 2>&1")
end
end
end
end
end
......@@ -37,6 +37,10 @@ module QA
def running?
`docker ps -f name=#{@name}`.include?(@name)
end
def read_file(file_path)
`docker exec #{@name} /bin/cat #{file_path}`
end
end
end
end
......
# frozen_string_literal: true
module QA
module Service
module DockerRun
class K3s < Base
def initialize
@image = 'registry.gitlab.com/gitlab-org/cluster-integration/test-utils/k3s-gitlab-ci/releases/v0.6.1'
@name = 'k3s'
super
end
def register!
pull
start_k3s
end
def host_name
return 'localhost' unless Runtime::Env.running_in_ci?
super
end
def kubeconfig
read_file('/etc/rancher/k3s/k3s.yaml').chomp
end
def start_k3s
command = <<~CMD.tr("\n", ' ')
docker run -d --rm
--network #{network}
--hostname #{host_name}
--name #{@name}
--publish 6443:6443
--privileged
#{@image} server --cluster-secret some-secret
CMD
command.gsub!("--network #{network} ", '') unless QA::Runtime::Env.running_in_ci?
shell command
end
end
end
end
end
......@@ -2,10 +2,9 @@
module QA
context 'Configure' do
# This test requires GITLAB_QA_ADMIN_ACCESS_TOKEN to be specified
describe 'Kubernetes Cluster Integration', :orchestrated, :kubernetes, :requires_admin, :skip do
describe 'Kubernetes Cluster Integration', :orchestrated, :kubernetes, :requires_admin do
context 'Project Clusters' do
let(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3d).create! }
let(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create! }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-with-k8s'
......@@ -35,18 +34,6 @@ module QA
expect(index).to have_cluster(cluster)
end
end
it 'installs helm and tiller on a gitlab managed app' do
Resource::KubernetesCluster.fabricate_via_browser_ui! do |k8s_cluster|
k8s_cluster.project = project
k8s_cluster.cluster = cluster
k8s_cluster.install_helm_tiller = true
end
Page::Project::Operations::Kubernetes::Show.perform do |show|
expect(show).to have_application_installed(:helm)
end
end
end
end
end
......
# frozen_string_literal: true
module QA
describe Service::DockerRun::K3s do
describe '#host_name' do
context 'in CI' do
let(:name) { 'k3s-12345' }
let(:network) { 'thenet' }
before do
allow(Runtime::Env).to receive(:running_in_ci?).and_return(true)
allow(subject).to receive(:network).and_return(network)
subject.instance_variable_set(:@name, name)
end
it 'returns name.network' do
expect(subject.host_name).to eq("#{name}.#{network}")
end
end
context 'not in CI' do
before do
allow(Runtime::Env).to receive(:running_in_ci?).and_return(false)
end
it 'returns localhost if not running in a CI environment' do
expect(subject.host_name).to eq('localhost')
end
end
end
end
end
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