Allow knative do be uninstalled:

- After uninstalling the knative helm chart it's necessary to also
remove some leftover resources to allow the cluster to be clean
and knative to be reinstalleable.
- Adds knative uninstall disclaimer
- Uninstall ksvc before uninstalling knative

Make list of Knative and Ingres resources explicit

- To avoid deleting unwanted resources we are listing exact
which resources will be deleted rather than simply deleting any
resource that contains istio or knative words.
This commit is contained in:
João Cunha 2019-07-31 11:58:38 +00:00 committed by Dmitriy Zaporozhets
parent fff0fc7b4c
commit d7c7ebf50a
13 changed files with 188 additions and 24 deletions

View File

@ -13,7 +13,9 @@ const CUSTOM_APP_WARNING_TEXT = {
), ),
[PROMETHEUS]: s__('ClusterIntegration|All data will be deleted and cannot be restored.'), [PROMETHEUS]: s__('ClusterIntegration|All data will be deleted and cannot be restored.'),
[RUNNER]: s__('ClusterIntegration|Any running pipelines will be canceled.'), [RUNNER]: s__('ClusterIntegration|Any running pipelines will be canceled.'),
[KNATIVE]: s__('ClusterIntegration|The associated IP will be deleted and cannot be restored.'), [KNATIVE]: s__(
'ClusterIntegration|The associated IP and all deployed services will be deleted and cannot be restored. Uninstalling Knative will also remove Istio from your cluster. This will not effect any other applications.',
),
[JUPYTER]: s__( [JUPYTER]: s__(
'ClusterIntegration|All data not committed to GitLab will be deleted and cannot be restored.', 'ClusterIntegration|All data not committed to GitLab will be deleted and cannot be restored.',
), ),

View File

@ -44,7 +44,7 @@ module Clusters
private private
def post_install_script def post_install_script
["/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml"] ["kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml"]
end end
def cluster_issuer_file def cluster_issuer_file

View File

@ -7,6 +7,7 @@ module Clusters
REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'.freeze REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'.freeze
METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'.freeze METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'.freeze
FETCH_IP_ADDRESS_DELAY = 30.seconds FETCH_IP_ADDRESS_DELAY = 30.seconds
API_RESOURCES_PATH = 'config/knative/api_resources.yml'
self.table_name = 'clusters_applications_knative' self.table_name = 'clusters_applications_knative'
@ -46,12 +47,6 @@ module Clusters
{ "domain" => hostname }.to_yaml { "domain" => hostname }.to_yaml
end end
# Handled in a new issue:
# https://gitlab.com/gitlab-org/gitlab-ce/issues/59369
def allowed_to_uninstall?
false
end
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name: name, name: name,
@ -76,12 +71,59 @@ module Clusters
cluster.kubeclient.get_service('istio-ingressgateway', 'istio-system') cluster.kubeclient.get_service('istio-ingressgateway', 'istio-system')
end end
def uninstall_command
Gitlab::Kubernetes::Helm::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files,
predelete: delete_knative_services_and_metrics,
postdelete: delete_knative_istio_leftovers
)
end
private private
def delete_knative_services_and_metrics
delete_knative_services + delete_knative_istio_metrics.to_a
end
def delete_knative_services
cluster.kubernetes_namespaces.map do |kubernetes_namespace|
"kubectl delete ksvc --all -n #{kubernetes_namespace.namespace}"
end
end
def delete_knative_istio_leftovers
delete_knative_namespaces + delete_knative_and_istio_crds
end
def delete_knative_namespaces
[
"kubectl delete --ignore-not-found ns knative-serving",
"kubectl delete --ignore-not-found ns knative-build"
]
end
def delete_knative_and_istio_crds
api_resources.map do |crd|
"kubectl delete --ignore-not-found crd #{crd}"
end
end
# returns an array of CRDs to be postdelete since helm does not
# manage the CRDs it creates.
def api_resources
@api_resources ||= YAML.safe_load(File.read(Rails.root.join(API_RESOURCES_PATH)))
end
def install_knative_metrics def install_knative_metrics
["kubectl apply -f #{METRICS_CONFIG}"] if cluster.application_prometheus_available? ["kubectl apply -f #{METRICS_CONFIG}"] if cluster.application_prometheus_available?
end end
def delete_knative_istio_metrics
["kubectl delete --ignore-not-found -f #{METRICS_CONFIG}"] if cluster.application_prometheus_available?
end
def verify_cluster? def verify_cluster?
cluster&.application_helm_available? && cluster&.platform_kubernetes_rbac? cluster&.application_helm_available? && cluster&.platform_kubernetes_rbac?
end end

View File

@ -59,6 +59,15 @@ module Clusters
) )
end end
def uninstall_command
Gitlab::Kubernetes::Helm::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files,
predelete: delete_knative_istio_metrics.to_a
)
end
# Returns a copy of files where the values of 'values.yaml' # Returns a copy of files where the values of 'values.yaml'
# are replaced by the argument. # are replaced by the argument.
# #
@ -97,6 +106,10 @@ module Clusters
def install_knative_metrics def install_knative_metrics
["kubectl apply -f #{Clusters::Applications::Knative::METRICS_CONFIG}"] if cluster.application_knative_available? ["kubectl apply -f #{Clusters::Applications::Knative::METRICS_CONFIG}"] if cluster.application_knative_available?
end end
def delete_knative_istio_metrics
["kubectl delete -f #{Clusters::Applications::Knative::METRICS_CONFIG}"] if cluster.application_knative_available?
end
end end
end end
end end

View File

@ -0,0 +1,5 @@
---
title: Allow Knative to be uninstalled from the UI
merge_request: 30458
author:
type: added

View File

@ -0,0 +1,64 @@
---
- meshpolicies.authentication.istio.io
- policies.authentication.istio.io
- adapters.config.istio.io
- apikeys.config.istio.io
- attributemanifests.config.istio.io
- authorizations.config.istio.io
- bypasses.config.istio.io
- podautoscalers.autoscaling.internal.knative.dev
- builds.build.knative.dev
- buildtemplates.build.knative.dev
- clusterbuildtemplates.build.knative.dev
- images.caching.internal.knative.dev
- certificates.networking.internal.knative.dev
- clusteringresses.networking.internal.knative.dev
- serverlessservices.networking.internal.knative.dev
- configurations.serving.knative.dev
- revisions.serving.knative.dev
- routes.serving.knative.dev
- services.serving.knative.dev
- checknothings.config.istio.io
- circonuses.config.istio.io
- deniers.config.istio.io
- edges.config.istio.io
- fluentds.config.istio.io
- handlers.config.istio.io
- httpapispecbindings.config.istio.io
- httpapispecs.config.istio.io
- instances.config.istio.io
- kubernetesenvs.config.istio.io
- kuberneteses.config.istio.io
- listcheckers.config.istio.io
- listentries.config.istio.io
- logentries.config.istio.io
- memquotas.config.istio.io
- metrics.config.istio.io
- noops.config.istio.io
- opas.config.istio.io
- prometheuses.config.istio.io
- quotas.config.istio.io
- quotaspecbindings.config.istio.io
- quotaspecs.config.istio.io
- rbacs.config.istio.io
- redisquotas.config.istio.io
- reportnothings.config.istio.io
- rules.config.istio.io
- servicecontrolreports.config.istio.io
- servicecontrols.config.istio.io
- signalfxs.config.istio.io
- solarwindses.config.istio.io
- stackdrivers.config.istio.io
- statsds.config.istio.io
- stdios.config.istio.io
- templates.config.istio.io
- tracespans.config.istio.io
- destinationrules.networking.istio.io
- envoyfilters.networking.istio.io
- gateways.networking.istio.io
- serviceentries.networking.istio.io
- virtualservices.networking.istio.io
- rbacconfigs.rbac.istio.io
- servicerolebindings.rbac.istio.io
- serviceroles.rbac.istio.io

View File

@ -255,6 +255,7 @@ The applications below can be uninstalled.
| GitLab Runner | 12.2+ | Any running pipelines will be canceled. | | GitLab Runner | 12.2+ | Any running pipelines will be canceled. |
| Ingress | 12.1+ | The associated load balancer and IP will be deleted and cannot be restored. Furthermore, it can only be uninstalled if JupyterHub is not installed. | | Ingress | 12.1+ | The associated load balancer and IP will be deleted and cannot be restored. Furthermore, it can only be uninstalled if JupyterHub is not installed. |
| JupyterHub | 12.1+ | All data not committed to GitLab will be deleted and cannot be restored. | | JupyterHub | 12.1+ | All data not committed to GitLab will be deleted and cannot be restored. |
| Knative | 12.1+ | The associated IP will be deleted and cannot be restored. |
| Prometheus | 11.11+ | All data will be deleted and cannot be restored. | | Prometheus | 11.11+ | All data will be deleted and cannot be restored. |
To uninstall an application: To uninstall an application:

View File

@ -7,19 +7,24 @@ module Gitlab
include BaseCommand include BaseCommand
include ClientCommand include ClientCommand
attr_reader :predelete, :postdelete
attr_accessor :name, :files attr_accessor :name, :files
def initialize(name:, rbac:, files:) def initialize(name:, rbac:, files:, predelete: nil, postdelete: nil)
@name = name @name = name
@files = files @files = files
@rbac = rbac @rbac = rbac
@predelete = predelete
@postdelete = postdelete
end end
def generate_script def generate_script
super + [ super + [
init_command, init_command,
wait_for_tiller_command, wait_for_tiller_command,
delete_command predelete,
delete_command,
postdelete
].compact.join("\n") ].compact.join("\n")
end end

View File

@ -27,9 +27,9 @@ module Gitlab
wait_for_tiller_command, wait_for_tiller_command,
repository_command, repository_command,
repository_update_command, repository_update_command,
preinstall_command, preinstall,
install_command, install_command,
postinstall_command postinstall
].compact.join("\n") ].compact.join("\n")
end end
@ -58,14 +58,6 @@ module Gitlab
command.shelljoin command.shelljoin
end end
def preinstall_command
preinstall.join("\n") if preinstall
end
def postinstall_command
postinstall.join("\n") if postinstall
end
def install_flag def install_flag
['--install'] ['--install']
end end

View File

@ -2815,7 +2815,7 @@ msgstr ""
msgid "ClusterIntegration|The URL used to access the Kubernetes API." msgid "ClusterIntegration|The URL used to access the Kubernetes API."
msgstr "" msgstr ""
msgid "ClusterIntegration|The associated IP will be deleted and cannot be restored." msgid "ClusterIntegration|The associated IP and all deployed services will be deleted and cannot be restored. Uninstalling Knative will also remove Istio from your cluster. This will not effect any other applications."
msgstr "" msgstr ""
msgid "ClusterIntegration|The associated certifcate will be deleted and cannot be restored." msgid "ClusterIntegration|The associated certifcate will be deleted and cannot be restored."

View File

@ -126,7 +126,7 @@ describe 'Clusters Applications', :js do
it 'shows status transition' do it 'shows status transition' do
page.within('.js-cluster-application-row-knative') do page.within('.js-cluster-application-row-knative') do
expect(domainname_form_value).to eq('domain.example.org') expect(domainname_form_value).to eq('domain.example.org')
expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installed') expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
end end
expect(page).to have_content('Knative was successfully installed on your Kubernetes cluster') expect(page).to have_content('Knative was successfully installed on your Kubernetes cluster')

View File

@ -48,7 +48,7 @@ describe Clusters::Applications::CertManager do
expect(subject.version).to eq('v0.5.2') expect(subject.version).to eq('v0.5.2')
expect(subject).to be_rbac expect(subject).to be_rbac
expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file))
expect(subject.postinstall).to eq(['/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml']) expect(subject.postinstall).to eq(['kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml'])
end end
context 'for a specific user' do context 'for a specific user' do

View File

@ -39,7 +39,7 @@ describe Clusters::Applications::Knative do
describe '#can_uninstall?' do describe '#can_uninstall?' do
subject { knative.can_uninstall? } subject { knative.can_uninstall? }
it { is_expected.to be_falsey } it { is_expected.to be_truthy }
end end
describe '#schedule_status_update with external_ip' do describe '#schedule_status_update with external_ip' do
@ -129,6 +129,46 @@ describe Clusters::Applications::Knative do
it_behaves_like 'a command' it_behaves_like 'a command'
end end
describe '#uninstall_command' do
subject { knative.uninstall_command }
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
it "removes knative deployed services before uninstallation" do
2.times do |i|
cluster_project = create(:cluster_project, cluster: knative.cluster)
create(:cluster_kubernetes_namespace,
cluster: cluster_project.cluster,
cluster_project: cluster_project,
project: cluster_project.project,
namespace: "namespace_#{i}")
end
remove_namespaced_services_script = [
"kubectl delete ksvc --all -n #{knative.cluster.kubernetes_namespaces.first.namespace}",
"kubectl delete ksvc --all -n #{knative.cluster.kubernetes_namespaces.second.namespace}"
]
expect(subject.predelete).to match_array(remove_namespaced_services_script)
end
it "initializes command with all necessary postdelete script" do
api_resources = YAML.safe_load(File.read(Rails.root.join(Clusters::Applications::Knative::API_RESOURCES_PATH)))
remove_knative_istio_leftovers_script = [
"kubectl delete --ignore-not-found ns knative-serving",
"kubectl delete --ignore-not-found ns knative-build"
]
full_delete_commands_size = api_resources.size + remove_knative_istio_leftovers_script.size
expect(subject.postdelete).to include(*remove_knative_istio_leftovers_script)
expect(subject.postdelete.size).to eq(full_delete_commands_size)
expect(subject.postdelete[2]).to eq("kubectl delete --ignore-not-found crd #{api_resources[0]}")
end
end
describe '#files' do describe '#files' do
let(:application) { knative } let(:application) { knative }
let(:values) { subject[:'values.yaml'] } let(:values) { subject[:'values.yaml'] }