Skip to content

Commit 566c34a

Browse files
Merge branch 'main' into chore/release-0.14.0
2 parents ce2284d + 11217c1 commit 566c34a

5 files changed

Lines changed: 64 additions & 33 deletions

File tree

api/v1alpha1/pluginpreset_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ const (
122122
PluginFailedCondition greenhousemetav1alpha1.ConditionType = "PluginFailed"
123123
// AllPluginsReadyCondition is set when all Plugins managed by the PluginPreset are created and ready.
124124
AllPluginsReadyCondition greenhousemetav1alpha1.ConditionType = "AllPluginsReady"
125+
// PluginDefinitionNotFoundCondition is set when the referenced PluginDefinition or ClusterPluginDefinition cannot be resolved.
126+
PluginDefinitionNotFoundCondition greenhousemetav1alpha1.ConditionType = "PluginDefinitionNotFound"
125127
)
126128

127129
// PluginPresetStatus defines the observed state of PluginPreset

go.mod

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ require (
4343
github.com/go-logr/logr v1.4.3
4444
github.com/google/cel-go v0.28.1
4545
github.com/google/go-cmp v0.7.0
46-
github.com/google/go-containerregistry v0.21.6
46+
github.com/google/go-containerregistry v0.21.7
4747
github.com/google/go-github/v88 v88.0.0
4848
github.com/hashicorp/go-retryablehttp v0.7.8
4949
github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4
@@ -58,7 +58,7 @@ require (
5858
github.com/vladimirvivien/gexe v0.5.0
5959
go.uber.org/zap v1.28.0
6060
golang.org/x/oauth2 v0.36.0
61-
golang.org/x/text v0.37.0
61+
golang.org/x/text v0.38.0
6262
gopkg.in/yaml.v3 v3.0.1
6363
helm.sh/helm/v3 v3.21.0
6464
k8s.io/api v0.36.0
@@ -108,7 +108,7 @@ require (
108108
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
109109
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
110110
github.com/dexidp/dex/api/v2 v2.4.0 // indirect
111-
github.com/docker/cli v29.4.3+incompatible // indirect
111+
github.com/docker/cli v29.5.3+incompatible // indirect
112112
github.com/docker/docker-credential-helpers v0.9.3 // indirect
113113
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
114114
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
@@ -207,15 +207,15 @@ require (
207207
go.uber.org/multierr v1.11.0 // indirect
208208
go.yaml.in/yaml/v2 v2.4.4 // indirect
209209
go.yaml.in/yaml/v3 v3.0.4 // indirect
210-
golang.org/x/crypto v0.51.0 // indirect
210+
golang.org/x/crypto v0.53.0 // indirect
211211
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
212-
golang.org/x/mod v0.36.0 // indirect
213-
golang.org/x/net v0.54.0 // indirect
214-
golang.org/x/sync v0.20.0 // indirect
215-
golang.org/x/sys v0.44.0 // indirect
216-
golang.org/x/term v0.43.0 // indirect
212+
golang.org/x/mod v0.37.0 // indirect
213+
golang.org/x/net v0.56.0 // indirect
214+
golang.org/x/sync v0.21.0 // indirect
215+
golang.org/x/sys v0.46.0 // indirect
216+
golang.org/x/term v0.44.0 // indirect
217217
golang.org/x/time v0.15.0 // indirect
218-
golang.org/x/tools v0.45.0 // indirect
218+
golang.org/x/tools v0.46.0 // indirect
219219
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
220220
google.golang.org/api v0.267.0 // indirect
221221
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect

go.sum

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
9292
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
9393
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
9494
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
95-
github.com/docker/cli v29.4.3+incompatible h1:u+UliYm2J/rYrIh2FqHQg32neRG8GjbvNuwQRTzGspU=
96-
github.com/docker/cli v29.4.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
95+
github.com/docker/cli v29.5.3+incompatible h1:nbEFfz774vBwQ5KRYv7c/AghjReqnGISvrRhzjV0evs=
96+
github.com/docker/cli v29.5.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
9797
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
9898
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
9999
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
@@ -193,8 +193,8 @@ github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7O
193193
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
194194
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
195195
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
196-
github.com/google/go-containerregistry v0.21.6 h1:T+yqQIlJXKrM98Om4DlW3GoWQAmhZuLMwoDOvVrtiUM=
197-
github.com/google/go-containerregistry v0.21.6/go.mod h1:U7MMSBIJynke2MVQrQk19NP9k/uQsGz/h0amIFSHMbo=
196+
github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU=
197+
github.com/google/go-containerregistry v0.21.7/go.mod h1:kjSbt7/zMsKLWfnHrIvKvhXHUw91jbe9DNjPPJ32gXE=
198198
github.com/google/go-github/v88 v88.0.0 h1:dZA9IKkPK1eXZj4ypngnpRj5FwdpTv4whix2PrQMP7M=
199199
github.com/google/go-github/v88 v88.0.0/go.mod h1:rufTDgn2N45wjhukLTyxmvc9nilSp3mr3Rgtt6b1MPw=
200200
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
@@ -482,30 +482,30 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
482482
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
483483
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
484484
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
485-
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
486-
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
485+
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
486+
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
487487
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
488488
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
489-
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
490-
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
491-
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
492-
golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
489+
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
490+
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
491+
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
492+
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
493493
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
494494
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
495-
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
496-
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
495+
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
496+
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
497497
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
498498
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
499-
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
500-
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
501-
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
502-
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
503-
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
504-
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
499+
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
500+
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
501+
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
502+
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
503+
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
504+
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
505505
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
506506
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
507-
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
508-
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
507+
golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk=
508+
golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys=
509509
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
510510
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
511511
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=

internal/controller/plugin/pluginpreset_controller.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var presetExposedConditions = []greenhousemetav1alpha1.ConditionType{
3838
greenhousev1alpha1.PluginSkippedCondition,
3939
greenhousev1alpha1.PluginFailedCondition,
4040
greenhousev1alpha1.AllPluginsReadyCondition,
41+
greenhousev1alpha1.PluginDefinitionNotFoundCondition,
4142
greenhousemetav1alpha1.ClusterListEmpty,
4243
greenhousemetav1alpha1.OwnerLabelSetCondition,
4344
}
@@ -93,6 +94,7 @@ func (r *PluginPresetReconciler) setConditions() lifecycle.Conditioner {
9394
return
9495
}
9596

97+
r.reconcilePluginDefinitionVersion(ctx, pluginPreset)
9698
readyCondition := r.computeReadyCondition(pluginPreset.Status.StatusConditions)
9799
ownerLabelCondition := util.ComputeOwnerLabelCondition(ctx, r.Client, pluginPreset)
98100
util.UpdateOwnedByLabelMissingMetric(pluginPreset, ownerLabelCondition.IsFalse())
@@ -127,8 +129,6 @@ func (r *PluginPresetReconciler) EnsureCreated(ctx context.Context, resource lif
127129

128130
clusters = clientutil.FilterClustersBeingDeleted(clusters)
129131

130-
r.reconcilePluginDefinitionVersion(ctx, pluginPreset)
131-
132132
err = r.reconcilePluginPreset(ctx, pluginPreset, clusters)
133133
if err != nil {
134134
return ctrl.Result{}, lifecycle.Failed, err
@@ -336,11 +336,18 @@ func (r *PluginPresetReconciler) reconcilePluginStatuses(
336336
func (r *PluginPresetReconciler) reconcilePluginDefinitionVersion(ctx context.Context, preset *greenhousev1alpha1.PluginPreset) {
337337
pluginDefinitionSpec, err := common.GetPluginDefinitionSpec(ctx, r.Client, preset.Spec.Plugin.PluginDefinitionRef, preset.GetNamespace())
338338
if err != nil {
339-
// Best-effort: clear the field to avoid reporting a stale version when the referenced definition can't be resolved.
340339
preset.Status.PluginDefinitionVersion = ""
340+
preset.SetCondition(greenhousemetav1alpha1.TrueCondition(
341+
greenhousev1alpha1.PluginDefinitionNotFoundCondition,
342+
greenhousev1alpha1.PluginDefinitionNotFound,
343+
err.Error(),
344+
))
341345
return
342346
}
343347
preset.Status.PluginDefinitionVersion = pluginDefinitionSpec.Version
348+
preset.SetCondition(greenhousemetav1alpha1.FalseCondition(
349+
greenhousev1alpha1.PluginDefinitionNotFoundCondition, "", "",
350+
))
344351
}
345352

346353
func isPluginManagedByPreset(plugin *greenhousev1alpha1.Plugin, presetName string) bool {
@@ -406,6 +413,12 @@ func (r *PluginPresetReconciler) computeReadyCondition(
406413
return readyCondition
407414
}
408415

416+
if conditions.GetConditionByType(greenhousev1alpha1.PluginDefinitionNotFoundCondition).IsTrue() {
417+
readyCondition.Status = metav1.ConditionFalse
418+
readyCondition.Message = conditions.GetConditionByType(greenhousev1alpha1.PluginDefinitionNotFoundCondition).Message
419+
return readyCondition
420+
}
421+
409422
if conditions.GetConditionByType(greenhousemetav1alpha1.ClusterListEmpty).IsTrue() {
410423
readyCondition.Status = metav1.ConditionFalse
411424
readyCondition.Message = "No cluster matches ClusterSelector"

internal/controller/plugin/pluginpreset_controller_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ var _ = Describe("PluginPreset Controller Lifecycle", Ordered, func() {
436436
// Note: ReadyCondition may not be true since Flux is not running, but Plugin should exist
437437
g.Expect(testPluginPreset.Status.TotalPlugins).To(Equal(1), "PluginPreset Status should show exactly one plugin in total")
438438
g.Expect(testPluginPreset.Status.PluginDefinitionVersion).To(Equal(pluginPresetDefinition.Spec.Version), "PluginPreset status should expose the version of the referenced PluginDefinition")
439+
g.Expect(testPluginPreset.Status.GetConditionByType(greenhousev1alpha1.PluginDefinitionNotFoundCondition)).ToNot(BeNil(), "PluginDefinitionNotFoundCondition should be present")
440+
g.Expect(testPluginPreset.Status.GetConditionByType(greenhousev1alpha1.PluginDefinitionNotFoundCondition).IsFalse()).To(BeTrue(), "PluginDefinitionNotFoundCondition should be false when the PluginDefinition exists")
439441
}).Should(Succeed())
440442

441443
By("verifying HelmRelease exists for the managed Plugin")
@@ -879,6 +881,20 @@ var _ = Describe("PluginPreset Controller Lifecycle", Ordered, func() {
879881
"PluginFailedCondition message should reference the non-existing PluginDefinition")
880882
}).Should(Succeed(), "PluginPreset should reflect the missing PluginDefinition in its status")
881883

884+
By("ensuring PluginDefinitionNotFoundCondition is set due to missing PluginDefinition")
885+
Eventually(func(g Gomega) {
886+
presetKey := types.NamespacedName{Name: pluginPresetName + "-missing-def", Namespace: test.TestNamespace}
887+
g.Expect(test.K8sClient.Get(test.Ctx, presetKey, pluginPreset)).To(Succeed())
888+
pdNotFoundCondition := pluginPreset.Status.GetConditionByType(greenhousev1alpha1.PluginDefinitionNotFoundCondition)
889+
g.Expect(pdNotFoundCondition).ToNot(BeNil(), "PluginDefinitionNotFoundCondition should be set")
890+
g.Expect(pdNotFoundCondition.IsTrue()).To(BeTrue(), "PluginDefinitionNotFoundCondition should be true")
891+
g.Expect(string(pdNotFoundCondition.Reason)).To(Equal(string(greenhousev1alpha1.PluginDefinitionNotFound)),
892+
"PluginDefinitionNotFoundCondition reason should be PluginDefinitionNotFound")
893+
g.Expect(pdNotFoundCondition.Message).To(ContainSubstring(nonExistingDefinitionName),
894+
"PluginDefinitionNotFoundCondition message should reference the non-existing PluginDefinition")
895+
g.Expect(pluginPreset.Status.PluginDefinitionVersion).To(BeEmpty(), "PluginDefinitionVersion should be empty when the PluginDefinition does not exist")
896+
}).Should(Succeed(), "PluginPreset should reflect the missing PluginDefinition via PluginDefinitionNotFoundCondition")
897+
882898
By("ensuring ReadyCondition is False")
883899
Eventually(func(g Gomega) {
884900
presetKey := types.NamespacedName{Name: pluginPresetName + "-missing-def", Namespace: test.TestNamespace}

0 commit comments

Comments
 (0)