From 4b60604236e0dc71d15af01f470f0fafac4e42f9 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:14:08 +0300 Subject: [PATCH 1/7] Keep resources with ownerReference in stack prune --- lib/k8s/stack.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index 5ae0483..4be9f98 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -123,13 +123,21 @@ def apply(client, prune: true) # @param resource [K8s::Resource] # @return [K8s::Resource] def keep_resource!(resource) - @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] = resource.metadata&.annotations.dig(@checksum_annotation) + annotation = resource.metadata&.annotations&.dig(@checksum_annotation) + return nil unless annotation + + @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] = annotation end # @param resource [K8s::Resource] # @return [Boolean] def keep_resource?(resource) - @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] == resource.metadata&.annotations&.dig(@checksum_annotation) + return true if resource.metadata&.ownerReference + + keep = @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] + return false unless keep + + keep == resource.metadata&.annotations&.dig(@checksum_annotation) end # Delete all stack resources that were not applied From af9d50cfb57c077b3a86b0cef98614e4ab5a5a74 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:19:01 +0300 Subject: [PATCH 2/7] Tune --- lib/k8s/stack.rb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index 4be9f98..03d29a6 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -101,6 +101,9 @@ def apply(client, prune: true) if !server_resource logger.info "Create resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" keep_resource! client.create_resource(prepare_resource(resource)) + elsif server_resource.metadata&.ownerReference + logger.info "Server resource #{server_resource.apiVersion}:#{server_resource.apiKind}/#{server_resource.metadata.name} in namespace #{server_resource.metadata.namespace} has an ownerReference and will be kept" + keep_resource! server_resource elsif server_resource.metadata&.annotations&.dig(@checksum_annotation) != resource.checksum logger.info "Update resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" r = prepare_resource(resource) @@ -123,19 +126,14 @@ def apply(client, prune: true) # @param resource [K8s::Resource] # @return [K8s::Resource] def keep_resource!(resource) - annotation = resource.metadata&.annotations&.dig(@checksum_annotation) - return nil unless annotation - @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] = annotation end # @param resource [K8s::Resource] # @return [Boolean] def keep_resource?(resource) - return true if resource.metadata&.ownerReference - - keep = @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] - return false unless keep + keep_annotation = @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] + return false unless keep_annotation keep == resource.metadata&.annotations&.dig(@checksum_annotation) end From 53d517a3a2e18a51a7effccfde8d0a4ee229329e Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:20:07 +0300 Subject: [PATCH 3/7] Add emptycheck --- lib/k8s/stack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index 03d29a6..47bd750 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -101,7 +101,7 @@ def apply(client, prune: true) if !server_resource logger.info "Create resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" keep_resource! client.create_resource(prepare_resource(resource)) - elsif server_resource.metadata&.ownerReference + elsif server_resource.metadata&.ownerReference && !server_resource.metadata.ownerReference.empty? logger.info "Server resource #{server_resource.apiVersion}:#{server_resource.apiKind}/#{server_resource.metadata.name} in namespace #{server_resource.metadata.namespace} has an ownerReference and will be kept" keep_resource! server_resource elsif server_resource.metadata&.annotations&.dig(@checksum_annotation) != resource.checksum From 37139d8b45edbb4a2da593d9919580ae3bb90062 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:20:40 +0300 Subject: [PATCH 4/7] Pluralize --- lib/k8s/stack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index 47bd750..9040b8c 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -101,7 +101,7 @@ def apply(client, prune: true) if !server_resource logger.info "Create resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" keep_resource! client.create_resource(prepare_resource(resource)) - elsif server_resource.metadata&.ownerReference && !server_resource.metadata.ownerReference.empty? + elsif server_resource.metadata&.ownerReferences && !server_resource.metadata.ownerReferences.empty? logger.info "Server resource #{server_resource.apiVersion}:#{server_resource.apiKind}/#{server_resource.metadata.name} in namespace #{server_resource.metadata.namespace} has an ownerReference and will be kept" keep_resource! server_resource elsif server_resource.metadata&.annotations&.dig(@checksum_annotation) != resource.checksum From b692bce37b6201e8758cf893cbc22b4530853b9f Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:21:35 +0300 Subject: [PATCH 5/7] Revert --- lib/k8s/stack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index 9040b8c..d794c31 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -126,7 +126,7 @@ def apply(client, prune: true) # @param resource [K8s::Resource] # @return [K8s::Resource] def keep_resource!(resource) - @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] = annotation + @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] = resource.metadata&.annotations.dig(@checksum_annotation) end # @param resource [K8s::Resource] From 94dee8af457e141cee546561703ffa3905557444 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 12:22:40 +0300 Subject: [PATCH 6/7] Variable name --- lib/k8s/stack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index d794c31..c711b31 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -135,7 +135,7 @@ def keep_resource?(resource) keep_annotation = @keep_resources["#{resource.kind}:#{resource.metadata.name}@#{resource.metadata.namespace}"] return false unless keep_annotation - keep == resource.metadata&.annotations&.dig(@checksum_annotation) + keep_annotation == resource.metadata&.annotations&.dig(@checksum_annotation) end # Delete all stack resources that were not applied From 2af438734a0bd5352ad5fc0cfca92651a544d530 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Wed, 4 Sep 2019 14:33:43 +0300 Subject: [PATCH 7/7] Better fix, some kind of spec --- lib/k8s/stack.rb | 5 ++--- spec/k8s/stack_spec.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/k8s/stack.rb b/lib/k8s/stack.rb index c711b31..6b8a25f 100644 --- a/lib/k8s/stack.rb +++ b/lib/k8s/stack.rb @@ -101,9 +101,6 @@ def apply(client, prune: true) if !server_resource logger.info "Create resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" keep_resource! client.create_resource(prepare_resource(resource)) - elsif server_resource.metadata&.ownerReferences && !server_resource.metadata.ownerReferences.empty? - logger.info "Server resource #{server_resource.apiVersion}:#{server_resource.apiKind}/#{server_resource.metadata.name} in namespace #{server_resource.metadata.namespace} has an ownerReference and will be kept" - keep_resource! server_resource elsif server_resource.metadata&.annotations&.dig(@checksum_annotation) != resource.checksum logger.info "Update resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}" r = prepare_resource(resource) @@ -164,6 +161,8 @@ def prune(client, keep_resources:, skip_forbidden: true) if resource_label != name # apiserver did not respect labelSelector + elsif resource.metadata&.ownerReferences && !resource.metadata.ownerReferences.empty? + logger.info "Server resource #{resource.apiVersion}:#{resource.apiKind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} has ownerReferences and will be kept" elsif keep_resources && keep_resource?(resource) # resource is up-to-date else diff --git a/spec/k8s/stack_spec.rb b/spec/k8s/stack_spec.rb index 4aca143..29382c8 100644 --- a/spec/k8s/stack_spec.rb +++ b/spec/k8s/stack_spec.rb @@ -80,6 +80,32 @@ end end + context "which has extra resources with owner references" do + let(:resources) { + subject.resources + } + + before do + extra_resource = subject.prepare_resource(subject.resources.pop) + extra_resource.metadata.ownerReferences = [ + { + :apiVersion=>"certmanager.k8s.io/v1alpha1", + :kind=>"Certificate", + :name=>"kontena-lens" + } + ] + returned_resources = resources.dup + returned_resources = returned_resources.map { |r| subject.prepare_resource(r) unless r.nil? } + allow(client).to receive(:get_resources).with([K8s::Resource, K8s::Resource]).and_return(returned_resources) + allow(client).to receive(:list_resources).with(labelSelector: { 'k8s.kontena.io/stack' => 'whoami' }, skip_forbidden: true).and_return(returned_resources + [extra_resource]) + end + + it "keeps the resource" do + expect(client).not_to receive(:delete_resource) + subject.apply(client, prune: true) + end + end + context "which has extra resources on server" do let(:resources) { subject.resources